"We will fix it later." Those four words have sunk more enterprise projects than any technology failure. Technical debt is not a developer concept, even though developers coined the term. It is a business concept with financial implications that compound exactly like financial debt. The problem is not borrowing. It is borrowing without understanding the interest rate.
What You Need to Know
- Technical debt is the gap between how software was built and how it should have been built, accumulated deliberately or accidentally
- Like financial debt, it compounds. Small shortcuts today become large constraints tomorrow
- Not all engineering debt is bad. Deliberate debt taken on for clear business reasons is a valid strategy
- The problem is untracked debt. Most organisations have no idea how much they're carrying or what it's costing them
The Original Metaphor
Ward Cunningham coined the term "engineering debt" in 1992. His point was elegant: sometimes it makes sense to ship code that isn't perfect, just as it sometimes makes sense to take on financial debt. You get to market faster. You learn from real users sooner. You capture an opportunity that won't wait.
But like financial debt, you have to pay it back. With interest.
The interest on engineering debt is the additional effort required for every future change. Code that was written quickly to meet a deadline becomes the code that makes the next feature take three times as long. An integration that was hacked together because the deadline was Tuesday becomes the integration that breaks every time the upstream system changes. A database schema that was designed for 100 users becomes the schema that collapses under 10,000.
Technical debt is invisible to the business until it is not. By the time it surfaces, the interest has been compounding for years.
John Li
Chief Technology Officer
The Four Types
Not all engineering debt is created equal. Martin Fowler's framework is useful here.
Deliberate and Prudent
"We know this isn't the ideal approach, but shipping now and refactoring next sprint is the right call." This is healthy debt. It's taken on knowingly, for a clear reason, with a plan to pay it down. Every project carries some of this, and that's fine.
Deliberate and Reckless
"We don't have time to do it properly." This is the dangerous kind. It's taken on knowingly, without a plan to address it. The shortcut becomes permanent. The "temporary" solution is still running three years later. The developer who wrote it has moved on and nobody understands how it works.
Accidental and Prudent
"Now we know how this should have been built." This is the debt that comes from learning. You made the best decision you could with the information you had. Now you have better information. The original approach isn't wrong, but it's no longer optimal. This is natural and inevitable.
Accidental and Reckless
"What's a design pattern?" This is debt born from inexperience or carelessness. No deliberate decision was made. The code was written poorly because nobody knew better or nobody cared enough to do it well. This is the most expensive kind because it's usually discovered late and is deeply embedded.
Why Business Leaders Should Care
Technical debt is often framed as a developer concern. "The engineers want to refactor." "The tech team says we need to clean things up." This framing makes it easy for business leaders to deprioritise. After all, the system works. Users aren't complaining. Why spend money on something invisible?
Here's why.
40%
of IT budgets spent on managing engineering debt rather than new capabilities
Source: Gartner, Market Guide for Software Engineering, 2018
Forty percent. That means for every dollar your organisation spends on technology, 40 cents goes to maintaining code that should have been written better, integrations that should have been designed differently, and architecture that should have been planned more carefully.
And it gets worse over time. Technical debt compounds. The longer it sits, the more expensive it becomes to address. Today's 40% becomes next year's 50%.
Velocity degrades. Features that should take two weeks take six because the codebase fights every change. New developers take months to become productive because the code is difficult to understand. Bug fixes introduce new bugs because the system is fragile.
Risk increases. Technical debt is where security vulnerabilities hide. Outdated dependencies. Unpatched libraries. Authentication mechanisms that were "good enough" three years ago. The longer debt sits, the larger the attack surface.
Talent leaves. Good developers don't want to spend their careers maintaining legacy code. If your codebase is drowning in debt, you'll lose the people best equipped to fix it. They'll go somewhere that invests in code quality. Then you're left with the debt and fewer people who understand it.
When to Take On Debt
Technical debt isn't inherently bad. Sometimes it's the right call.
When speed to market matters more than perfection. If there's a genuine business opportunity that requires shipping in four weeks instead of eight, taking on deliberate, documented debt is rational. The key word is "documented." Write it down. Estimate the cost to fix it. Schedule the fix.
When you're still learning. Early in a project, you don't know everything. Building quickly, learning from users, and then rebuilding with better understanding is often faster than trying to design the perfect system upfront.
When the debt is isolated. A shortcut in a module that's self-contained and can be rewritten without affecting the rest of the system is lower risk than a shortcut in the core architecture.
When to Pay It Down
Before scaling. Debt that's manageable at 100 users becomes catastrophic at 10,000. If you're planning to grow, pay down the debt that sits in your critical path first.
When velocity drops. If feature delivery is slowing down and the team reports that the codebase is the reason, that's the debt talking. Ignoring it doesn't make it cheaper.
When you're about to build on top of it. If the next feature depends on a component that's carrying heavy debt, fix the foundation before building higher. Otherwise, the new feature inherits all the problems of the old code.
Continuously. The best approach isn't a quarterly "debt sprint." It's a continuous allocation - 15-20% of engineering time dedicated to paying down debt alongside feature work. This prevents the debt from accumulating to the point where a major remediation effort is needed.
The Conversation We Should Be Having
Technical debt shouldn't be a negotiation between engineers who want to fix things and business leaders who want new features. It should be a shared understanding of a business asset that's depreciating, and a deliberate strategy for managing that depreciation.
The question isn't "should we refactor?" The question is "what's the cost of not refactoring, and when does that cost exceed the cost of doing it?"
That's a business decision. Treat it like one.
