Thirty spokes are joined together in a wheel,
but it is the center hole
that allows the wheel to function.We mold clay into a pot,
but it is the emptiness inside
that makes the vessel useful.We fashion wood for a house,
but it is the emptiness inside
that makes it livable.We work with the substantial,
Tao Te Ching, chapter 11
but the emptiness is what we use.
In software engineering, we work with code, but understanding is what we use.
When mentoring new engineering team members, I have sometimes told them, “Understanding is more important than delivery.” My meaning is, “Take your time. Plan to be here for a while. Ask questions, build mental models, get things right and know why they’re right. Spending an extra day now on deep understanding will save weeks or months in the future.”
With some people, it’s hard to convince them of this. I think it’s about psychological safety. Being new, they want to prove themselves valuable to the company, and on the surface, companies value delivery. So they try to move tickets across the board, and are afraid to pause that movement for any questions that aren’t obviously blockers. In these cases, I do my best to show that I welcome curiosity, and hope their sense of safety increases with time. There’s only so much I can do. I’m not a manager, just a senior IC, so it won’t be me writing their performance review.
It’s less common, but some people have the opposite problem. Their curiosity is insatiable to a fault. Their insecurity shows up in a different way: rather than over-focusing on delivery, they are so afraid of delivering something incorrect that they have trouble moving forward. I find it harder to help someone who’s stuck in this way, because this is also my weakness. It’s my instinct to spend time generously on questions. If a new person with this disposition is trying to deliver on a project where I’m a subject matter expert, they are going to have a tough time. It’s too tempting to just keep bringing me new, interesting questions and building more understanding. But past a certain point, understanding that is not used to deliver something becomes anemic. In these cases, the best I can do is direct their focus back to the smaller, more specific problem at hand. Was I wrong in what I told the other person? Is understanding always more important?
The rarest case of all is when someone sets a fast pace with their work, but is also building a deep understanding as they go. They bring curious questions, but are eager to keep moving forward once the gaps in their understanding are filled. I’ve noticed that written notes or “documenting as you go” are usually essential to this work style. This intentional building of understanding is an underrated superpower. To some people, the benefits may not be obvious. To others, it would be inconceivable to work any other way. Take it from someone who didn’t used to do it: it’s essential to professional growth, and it’s learnable.
But is it even meaningful to say understanding is more important than delivery? Doesn’t it all come down to delivery in the end? To the new team member over-focused on delivery, I said above, “Spending an extra day on deep understanding will save weeks or months” … of what? Future delivery time, of course!
That sounds similar to saying you should put money in your retirement fund now because it will grow into much more in the future. Is it the same principle? In other words, is the value of understanding reducible to future delivery?
Yes and no. It’s true that the ultimate purpose of software is to benefit users, which it can only do if delivered. And generally speaking, software can only generate revenue if delivered (especially now that money isn’t free anymore). If this were the final word, my Taoist metaphor wouldn’t be apt. The useful space inside a house is not reducible to future walls; that makes no sense.
So then what’s the “no” part? Bear with me.
One explanation for the Tao quotation above is simply that a wheel needs space for the axle, a bowl needs space for the contents, and a house needs space for living. But this is missing the point.
A house doesn’t just “need space for living.” The space is the whole point of the house. The walls are just there to define and protect the space. A rolly thing with nowhere to put the axle isn’t a wheel; a solid half-sphere isn’t a bowl. The substances are only there in support of the emptiness.
In the same way, the code we deliver defines and protects understanding. As a software product grows, and generations of engineers onboard, make changes, and offboard, the existing code is the primary source of the understanding they labour to build. And neglected code can fail to protect understanding, just as a house, unmaintained, can fail to protect the space inside.
From this point of view, it’s not code that’s fundamental to a software business, but the diverse and overlapping understanding of its employees. Without that understanding, the code can’t be operated in production, customers can’t be supported, markets can’t be “gone to”, and beneficial sales agreements can’t be reached. A software engineer’s job is about more than code, a software business depends on more than software engineering, and all business functions depend on a correct and deep understanding.
Furthermore, that understanding is its own thing: it is never perfectly embodied or fully expressed in any single deliverable, nor in the sum of all deliverables, nor in the sum of all business functions. In a successful business, every deliverable contains intentional trade-offs, and no function or job role is as important as the process of collaborating across functions to create clarity and purpose. When we talk of people in senior roles having a great impact, we mean precisely that they created collaborative clarity and purpose. For every successful software business, the main product, the result of 90% of the labour, is always understanding.
They may also produce new releases of an app, data pipelines, financial plans, sales pitches, marketing materials, etc. You know, deliverables.
90% may sound radical, but it’s basically a re-statement of the famous principle that software engineers spend more time reading code than writing it. The percentage may be lower for newer products, but it quickly rises. In my experience, the same is true of all business functions and all levels. The difference being, at entry levels it’s mostly your own understanding that you labour to build, while at higher levels, you lead others in building it together.
If you want to remain a delivery reductionist, you could simply say that the purpose of that 90% is to ensure you deliver correctly with the remaining 10%. But this is strange to me. “Measure nine times, cut once?” Or perhaps the concept is of the company itself as an engine, so inefficient that it must be maintained for nine hours to run for one hour.
To me it makes more sense simply to say that, while code is the body of a software product, understanding is the soul — and it resides in the humans who work on it. (Yes, there are things to say here about AI coders; no, they are not in scope for this article.)
So, yes, if you squint, you can reduce understanding to delivery in the same way you can assign everything a dollar value, if that’s how you want to look at it. But no, it’s not truly reducible. Fundamentally, a product is the understanding of its makers, nothing more or less — with the caveat that, without delivery, there is nothing to understand.
“Okay,” someone will say, “but we have customers who are not going to renew unless we deliver this feature next month. Are you saying we shouldn’t prioritize delivery?”
And others will say, “Our codebase has devolved to the point where people hardly understand it anymore. It’s so bloated, I could rewrite it to do the same thing with 75% less code. Just give me a month.”
While I believe understanding is fundamental, that’s not the same as saying it should be a higher priority than delivery.
Look, I’m biased here — as I alluded to above, I’m curiosity-driven. My favourite video game ever is The Witness, which is about the rich internal experience of epiphany, while providing basically no extrinsic reward for completing its many gruelling puzzles, other than the chance to reach greater levels of challenge and understanding.
I’ve spent most of the above words exhalting understanding because we don’t talk about it enough. It’s that essential thing which is invisible to the eye, as Saint-Exupรฉry would say, easily forgotten in the otherwise admirable impulse to measure outcomes and systematize improvements.
And yet, understanding needs embodiment through delivery. If you’re that person who knows how to reduce the code by 75% and still do the same thing, I hope you’re not waiting around for the chance to finally spend a whole month on that. It won’t happen, and in the meantime your understanding is a friendly ghost, staving off trouble here and there, and fading away as soon as you move to a different team or company. Better to identify the places where you can spend a day or a week to reduce the code by 5%, ask for that time, celebrate the win, repeat.
As for the customers who will be gone next month, it’s true that sometimes compromises and shortcuts are essential. But notice what’s also essential in these cases: understanding what compromise you’re making, and why. Understanding the impact on your code or your feature set, the protectors of long-term understanding. Understanding the plan to remediate the impact after the customers are appeased. Communicating the plan — which is to say, building understanding together.
If the impulse to measure and systematize sometimes forgets understanding, then can we measure understanding itself?
In theory, various measures of quality, such as defect density, code coverage, and time to detect and resolve incidents, can be proxies for understanding. Good understanding loosely correlates to quality. But measuring quality is already hard, and understanding is something even more indirect and nebulous, though fundamental.
Ultimately, the impulse to measure understanding is putting the cart before the horse. Although understanding shines through every deliverable, understanding itself is a first-person phenomenon. When it comes to measurement, it’s not really about measuring understanding; it’s about understanding what you’re measuring.
This is why soft data, like conversations and anecdotes, are essential to contextualize hard data, like time to detect and resolve incidents. For example, the actual meaning of having a low TTD/TTR could be many things. Maybe it’s due to robust monitoring and runbooks. Or maybe it’s because everyone is afraid to make ambitious changes. Or maybe it’s due to that one person who deftly saves production every week, because no one else knows what to do. Measurement is only actionable if you first understand what you’re measuring.
If you’ve ever tried any kind of mindfulness meditation, this may be starting to feel familiar. The tricky thing about mindfulness is that the method is the same as the goal.
For most practitioners, the goal of mindfulness meditation is generally some kind of ongoing improvement in your abilities, such as concentration, focus, wellbeing, compassion, etc. Often practitioners are instructed to put aside thoughts about goals and self-improvement — but it’s hard to avoid the fact that something makes you feel that it’s worth your time.
Based on this goal, it’s natural to feel that a given meditation session was “good” or “bad” based on what happened with your attention. Did you maintain focus on X (e.g. your breath), or did you get repeatedly side-tracked into thoughts about work or relationships? Ultimately, both are valid and useful experiences. Having an object of focus establishes a basis to practice mindfulness, not through value judgments of success or failure, but through noticing what your mind does in any case.
- Did you think of a thorny project at work? Just notice that.
- Did you reminisce about your vacation last year? Just notice that.
- Did you worry about a relationship? Be aware of that too.
In the same way, as software engineers, we’re invested in promoting understanding of the systems we work on — our own understanding, as well as helping to build that of others. Having a delivery goal establishes a basis to develop that understanding, not through blindly forging ahead, nor through perfect planning, but by noticing how the goal interacts with reality, evaluating, communicating, and re-adjusting as we go.
- Is that API not working as specced? Understand that.
- Does the timeline require compromises? Understand those.
- Does the complexity of a system pose a risk to delivery? Understand the risk and decide what to do together.
- Have you been tasked with measuring department outcomes? Understand what you’re measuring.
As the scope of the problem increases, “understand” refers not only to what happens in your own mind, but to communicating and building that understanding with others.
Understanding is fundamental to the health of a codebase, but it’s also bigger than that. No matter what the problem at hand, understanding comes first. Even if understanding is being compromised, understanding the compromise comes first.
In this way, understanding in software engineering is like attention in mindfulness meditation, or awareness in traditions like Advaita Vedanta, or emptiness in the quotation from the Tao Te Ching. Whether we value it or not, understanding is the ultimate origin, method, and purpose of everything we do, but that doesn’t mean you can put it on autopilot. Cultivating it deliberately and collectively leads to much better outcomes. The best way to cultivate understanding is through what you deliver, but knowing this can fundamentally change what you deliver.
Now the three “new team member” archetypes from the intro make sense: the first focuses only on delivery, and so is not actually working on the product, because the product consists of understanding. The second focuses only on understanding, which slips through their fingers like water.
The third archetype sees delivery as the means to build understanding. Their various outputs are huge, in terms of code, yes, but also notes, diagrams, documentation. All that “extra” output doesn’t feel like extra work, because it isn’t the product — not even the code. The product is what comes alive in their mind — a story told and re-told, a plot that thickens, a journey to be shared.