While working with the same people in the same problem domain for a long time, it's extremely common for people to take shortcuts when describing usage of a technical system.
- "When the user submits the form, it fails"
- "When the process runs out of memory and dies, it will automatically restart"
- "Oh yeah the app is slow right now"
- "This API is harder for a user to use correctly"
There's a general idea of what these statements mean, and they communicate the right idea most of the time (otherwise they wouldn't be said!). But in more heated conversations or whenever we are debugging particularly tricky problems, these statements can have multiple slightly different meanings! Conversations quickly fall apart and end with people talking past each other. Instead of communicating technical information, you are presented with a game of linguistic forensics to decipher what is being said.
This can get even worse when using tooling with a large specific vocabulary. Operations teams might be used to talking about machines and processes, but when operating with Kubernetes, it can be easy to use "machine" to describe a Pod, "container" to describe a Pod, "worker" to describe a Pod, "machine" to describe a node.... the tooling might be at fault for "bad design decisions", but ultimately if you're using it you'll save yourself time in the long run to just use unambiguous words.
How do we get to precision in discussions?
There is the (vague!) advice of "imagine you are in the other person's shoes" but that requires a strong theory of mind if you're under time pressure, stress, and general confusion about what a coworker might be saying.
And a lot of times the advice is in forms of "concession". You spend time explaining something you already undersatand, often unsuccessfully. You try to concede points you disagree with just to move conversations forward. Ultimately fundamental misunderstandings remain and people can walk away unsatisfied.
Some things that help me in getting to precision:
Making Sure The "Who" And The "What" Are Clear
There are a lot of layers in the systems we work with, so by pointing exactly to which systems are being talked about, we can more quickly get to any sticking points and not get sidetracked by asking the wrong people or looking at the wrong systems.
"When the user submits the form, it fails" can become any of the following (with different consequences):
- after looking at the network tab in the browser dev tools: "When the user makes this kind of API request, the API returns the following error"
- after seeing a screenshot the user took: "When the user submits the form, they see this error message" or "when the user tries to submit this form, the submission button looks disabled and clicking doesn't seem to do anything."
- after being told by a user that the page fails: "The user said that when they submit the form, they get a server error page." (Importantly noting the source of information)
Of course many of these require a bit more investigation, and when you don't have that luxury, simply being clear about the source of information and what you (don't) know, saying: "The user is reporting that when they submit this form, it is failing" helps to guide discusison and work towards collecting more information (what kind of data? Does a request happen? Are there any user-visible errors?), rather than going into guesswork directly.
Similarly, when discussing how a background task system keeps itself healthy you might say "when running out of memory, the process restarts itself", but with more precision you could actually communicate important details for the reader. That might become:
- When the process has been killed, supervisor will restart it (this both communicates the general process lifetime management and who is handling restarts)
- When the pod uses too much memory, kubernetes will shut it down, then try to bring it back up. (Points out at what level the issue is handled and that it is an active process)
Providing Supporting Evidence
Whenever describing a situation, we are often making several assertions about what is happening. "The app is slow", well... that's interesting. How do you know this?
You can turn your conjectures into ironclad statements very quickly, fortunately! Just provide the evidence!
"The app is slow" can become "The app seems slow (image of the statsd graphboard of the 90th percentile of request duration spiking upwards)". Even better, including a link to a live graph of this data.
Maybe the app seems slow because you loaded it on your machine. It's totally fine to say "the app seems slow on my machine". That way you're being honest about the data colleciton method (and perhaps that's enough in your specific context).
Similarly, including raw log lines when discussing an issue with some requests can provide a lot of context at almost no cost.
When discussing technical designs, if one is balancing the merits of two solutions, providing visual aids to describe each solution (even some basic flowcharts) can help to highlight their differences. And by providing that extra context with this supporting evidence, misunderstandings can be cleaned up more quickly.
"This API design is harder to use" can become "When using this API, a user will need to associate various IDs on their end and require a database to store those, whereas this alternative design would not require any user-side storage." Writing out such flows in words ("because X") can get a bit long, but if you have a nice flow chart or code sample then that can do the talking and provide space for a reasonable response.
"If this old protocol is a car, the new one is like a plane" might sound fun in your head, but people reading it are now wondering which of the following was meant:
- The new protocol is faster
- The new protocol moves more data at once, but with larger fixed costs
- The new protocol is safer
- The new protocol has more limited entrypoints, compared to the old one
- The new protocol requires more regulatory approval
Analogies work when the things are the same, up until the point that things are in fact different. When referring to other things that exist, you carry in all of the little details of the other existing thing with all of its peculiraties.
There are some exceptions (rigorous analagies like the electronic-hydraulic analogy have a theoretical basis and a lot of work behind them), but personally I have rarely heard an analogy that doesn't show up with baggage.
State Facts First, Leave Opinions Until Later
Especially in technical design discussions, the point of a technical explanation is often to advocate for a certain kind of decision, over another. They are about persuasion and convincing.
There's sometimes an urge, then to state the conclusion up front, and then provide the supporting evidence. Or to prepare people for the conclusion by emphasizing some judgement (lots of "this doesn't make sense", "this is the simplest way forward", or "this is not usable" utterances).
But really, if the objective is to convince someone of an idea, you should first present the truth. After you've laid out your facts you can provide your opinion. That will limit debatable parts of your discussion, and establish ground truths.
"This interface design is going to be much simpler for doing tasks A, B and C" can become "In this new design, task A can be done in less clicks. Information about B will be displayed in a more prominent location. And C is now doable through the UI. This seems very good to me."
Code review comments like "this is real messy, how about moving this bit of code to a second function" become "This bit of code could be moved to a second function. That seems cleaner to me".
This could seem like trying to just protect people's pride, bu it's mostly about trying to reduce the surface area of debate and find out what actually is common ground.
None of these are hard rules, of course, but they are all points that I try to think about when writing up anything technical.