The conversation usually ends the same way. An engineering team flags that a significant portion of the codebase needs to be addressed before the next major feature can safely be built. A deadline gets cited. The response from the business is some version of "can't we just do both?" and the refactoring work disappears into the backlog, indefinitely. The problem is rarely that the business doesn't care about code quality. The problem is that engineers explain technical debt as a technical problem, when it is a business risk.
What technical debt actually is
Technical debt is not messy code. It is not a lack of tests, or an old framework, or a poorly named variable. Those are code quality problems, and while they matter, they are not what makes technical debt a strategic concern.
Technical debt is the accumulated cost of decisions made quickly in the past that now slow down delivery in the present. It is the architectural shortcut taken to meet a deadline three years ago that now requires two extra days of coordination every time the checkout flow is touched. It is the database schema designed for a ten-user system now struggling with ten thousand. It is the absence of automated tests that means every deployment carries a risk that cannot be quantified.
The financial analogy is imperfect but useful: like financial debt, technical debt accrues interest. Each month of not addressing it, the cost of working around it compounds. Unlike financial debt, it never gets paid off on its own.
Why the usual explanations fail
The most common framing engineers use is velocity. "This is slowing us down." Sometimes they pull up a chart. The business hears this as: the engineers want time to tidy up their work. This sounds like perfectionism — especially when there is a backlog of feature requests and a roadmap to deliver.
The second common framing is risk. "This could cause a production incident." This is closer to the right language but too abstract. Incidents happen, and the business has absorbed them before. A vague risk framing does not make the case for carving out sprint capacity.
The third framing — and the one I hear most often from engineers who genuinely understand the problem — is the correct diagnosis delivered to the wrong audience. "The architecture is not designed for what we are now trying to build." This is technically accurate and completely meaningless to anyone who is not a software engineer.
The framing that works: delivery capacity
Reframe technical debt as delivery capacity. Not "this is a technical problem" but "this is why we cannot commit to the roadmap you want us to commit to."
The question to answer is not "what is wrong with the codebase?" It is "what would we be able to ship in the next quarter if we addressed this, versus if we don't?"
If the answer is "we could ship the new reporting module in two weeks instead of six," that is a business case. If the answer is "we could safely deploy twice a week instead of twice a month," that is a business case — especially if DORA metric data supports it. If the answer is "we would spend forty fewer engineering hours per month on production support," that is also a business case, and one with a direct cost attached.
Making it tangible
Quantification is hard, and the temptation is to avoid it because the estimates will be wrong. Give rough numbers anyway. "This area of the codebase costs us approximately three days of engineering time per sprint in coordination, rework and cautious testing around the known unstable parts." That is a rough estimate. It is also far more compelling than "this is a technical debt problem."
Three approaches that produce usable data:
- Track the friction cost. Ask the team to estimate, at the start of each sprint, how many story points of capacity are effectively unavailable because of known debt in the area they are working in. After three or four sprints, you have data.
- Use production signals. The areas with the most incidents, the longest mean time to restore, or the highest change failure rate are usually the most indebted parts of the system. Those numbers are already tracked in most organisations — they just are not being connected to the debt conversation.
- Compare cycle times. If a feature in a clean part of the codebase takes half the time of a similar-complexity feature in a debt-heavy area, that gap is the interest payment. Make it visible.
Getting the time
Once the framing is right, the ask becomes easier. You are not asking for time to clean up code. You are proposing an investment that will increase delivery throughput by a specific amount, with supporting evidence.
The most effective structural approach I have seen is an explicit allocation: a standing agreement that a fixed percentage of each sprint — typically fifteen to twenty percent — is reserved for technical health work. This is not negotiated feature by feature. It is a structural decision made at the team level that removes the "can't we skip it this sprint?" conversation entirely.
The worst approach is the big-bang refactor. A six-week project to rewrite a service that produces no visible output until the final week is very hard to defend when a competitor ships a new feature. Incremental improvements, attached to feature work where possible, are easier to sustain and considerably harder to cancel.
The business usually comes around when they see the numbers. The challenge is getting far enough into the conversation to show them.
Back to Insights