Where we draw the line?
Hey!
Welcome back to another week of musings.
I hope you had a chance to slow down a bit this weekend. On my side, I had to deal with a SEV0 at work and spent most of my time in front of a computer. Here's to a good week!
Was this forwarded to you? You can subscribe here!
Things I enjoyed in the past week
- The Principal Engineer’s Path: Skills, Strategies, and Lessons Learned is a nice talk about the path to principal engineer, and how careers are never linear.
- Fisherman’s Wharf Walking Guide. I follow this photographer, and their newsletter has a lot of recommendations for walking around the city!
Lately, I've been thinking a lot about where the line actually is with tech debt.
I recently read Tech debt metaphor maximalism, and I liked the framing a lot.
The basic idea is that not all debt is bad. Some debt is how you move faster. The problem is not debt by itself. The problem is whether you understand the interest you're paying and whether you're getting too close to the ceiling.
In practice, we're always making trade-offs. We never have perfect information when we design systems. We don't know which requirements will change, which edge cases will become core use cases, or which integration will become weirdly load-bearing later (Hyrum's Law).
Some tech debt is inevitable when building software.
What I'm finding, though, is that this can go in two very different directions.
One way we accept that shipping requires compromise is by trying to find the maximum amount of debt we can live with while still delivering.
Otherwise, we normalize every awkward part of the system until nobody even recognizes it as debt anymore.
You cannot pay it all down
There isn't a world where a team gets to "zero tech debt." There's always something that could be cleaner, more scalable, easier to reason about, or less annoying to operate. If a team tries to fix every imperfection before shipping, they end up not shipping.
So I agree with the basic premise that we have to live with some amount of debt. To me, the question is: at what level of debt can we still move?
That's the sweet spot. Enough structure that the system is still understandable and changeable, but not so much purity-seeking that every delivery turns into an architecture exercise.
The danger is when debt becomes invisible
The friction I've been seeing on teams is not usually people openly arguing for more tech debt.
It's people looking at painful parts of the system and saying, "That's just how it works." And sometimes that's true. Every system has constraints.
But sometimes what we're calling "the way the system works" is really just a workaround that survived long enough.
The cost just gets absorbed into daily life. Feature work slows down. Coordination gets harder. Testing gets more fragile. Delivery needs more tribal knowledge. But because the pain is familiar, nobody really reacts to it anymore.
And that's usually the point where the debt is no longer helping you ship. Now it's just preserving the status quo at an ever higher cost.
Draw a line in the sand
I think teams need to do this exercise explicitly.
Draw a line in the sand and ask: which parts of this system are acceptable compromises, and which parts are things we do not want to carry forward?
At the beginning of a company, velocity can justify a lot. You're trying to find product-market fit, acquire customers, and learn quickly. A rough solution that works can be exactly the right choice.
Later on, the context changes. Maybe growth slows. Maybe getting the next customer is harder than it used to be. Maybe the business is no longer rewarded for pure speed but for better margins, greater reliability, or greater leverage from its existing customer base.
Re-architecture is not the same as rewriting everything
And when I say rethink, I do not mean "rewrite the whole thing."
That's usually not realistic. Full rewrites are too expensive, too risky, and too hard to justify while the current system still has to keep running.
What does make sense is targeted re-architecture.
You look for the places where maintenance costs keep rising while returns keep shrinking. You look for places where an off-the-shelf solution is now good enough, even if it wasn't when you first built your custom version.
Sometimes the smartest thing a team can do is stop owning a solved problem. Sometimes the smartest thing is to redesign a specific subsystem so the rest of the product can keep evolving.
Debt is only acceptable while it still buys you something
I think that's the line.
Tech debt is acceptable when it's still buying speed, learning, or delivery capacity that the business genuinely needs.
The question is whether it's still helping the team do its job.
If the answer is no, then keeping it "because that's how the system works" is not pragmatism. It's inertia.
Your turn!
Have you ever been on a team where everyone accepted painful parts of the system as just "the way things are"?
Were you able to draw a line and change something meaningful, or did the status quo win?
Let me know by replying to this email!
Happy coding!