Ward Cunningham coined the term "technical debt" in 1992 to describe the cost of taking shortcuts in software design. The metaphor is apt: like financial debt, technical debt accrues interest over time. The longer you carry it, the more it costs.
What technical debt actually is
Technical debt isn't bugs. It's not missing features. It's the gap between the design your codebase has and the design it would need to evolve cleanly.
It accumulates through:
- Shortcuts taken under deadline pressure ("we'll clean this up later")
- Decisions made without full information that became wrong as requirements evolved
- Dependencies on outdated libraries or deprecated patterns
- Missing tests that make changes dangerous
- Architecture that made sense at 10,000 users but not at 1,000,000
Some debt is intentional and rational. Moving fast to validate a market hypothesis and cleaning up later is a legitimate trade-off. The problem is when the cleanup never happens.
How interest compounds
The compounding mechanism: every new feature built on top of messy code takes longer, introduces more bugs, and creates more debt. A codebase with high debt doesn't just slow you down today — it makes every future change slower.
A development team that ships 10 features a month on a clean codebase might ship 4 features a month on a heavily indebted one. The 60% productivity loss is invisible until you've experienced both states.
The signals
You have a technical debt problem if:
- Engineers estimate features at 3× what they'd take in a greenfield codebase
- Bug rates are high despite effort on quality
- New engineers take months to become productive
- "Simple" changes have unexpected side effects
- Fear of changing existing code is common in engineering conversations
When to pay it down
Not all debt warrants immediate repayment. A legacy system that's stable and rarely changed can carry significant debt without causing harm. The calculus changes when:
- The system is actively developed
- The debt is concentrated in the areas that change most
- Developer velocity has visibly degraded
- You're about to scale the team significantly
A targeted refactor of the most-changed, most-painful parts of a codebase delivers more value than a wholesale rewrite.
The rewrite trap
"Let's rewrite it from scratch" is the siren song of technical debt. Full rewrites are expensive, risky, and often reproduce the same problems in new code. The second system effect is real — the team that built the messy first system now builds a slightly less messy second system, while the original continues to serve users.
Incremental improvement, targeted at high-leverage areas, almost always wins over wholesale replacement.