Technical debt is not a synonym for bad code. It is the gap between the fastest way to ship something and the way you would build it with complete information and unlimited time — a real tradeoff with a real cost, not a moral judgment about the person who wrote it. Understanding that distinction changes how you talk about it with a non-engineering stakeholder, and it changes what you actually do about it.
The core idea
Ward Cunningham coined the metaphor in 1992 to describe something specific: shipping code based on your current understanding of a problem is like taking a loan. You get to market faster. The "interest" is the extra effort every future change costs because the code does not reflect what you have since learned. Cunningham's own point was that this is not laziness — it is a reasonable bet, made deliberately, that you will repay later with what you learn from shipping.
The metaphor got stretched over the following decades to mean almost any code someone dislikes. That dilution is the actual problem with the term today: when "technical debt" means everything from a genuinely risky shortcut to a naming convention someone finds ugly, it stops being useful in a planning conversation with a product manager who has to decide what to prioritize.
Deliberate debt vs accidental debt
| Type |
How it happens |
Example |
Fix strategy |
| Deliberate, known cost |
Team chooses the fast path with a plan to revisit |
Hardcoding a config to hit a launch date |
Track it explicitly; schedule the repayment |
| Deliberate, unknown cost |
Team knows the tradeoff but not its true size |
Skipping a caching layer "for now" |
Measure before committing more debt on top |
| Accidental, known |
Team learns after the fact that the design was wrong |
An abstraction that fit 3 use cases, not 30 |
Refactor once the pain is confirmed |
| Accidental, unknown |
Nobody has noticed yet |
An undocumented assumption baked into five call sites |
Surfaces during an incident or onboarding |
Martin Fowler's technical debt quadrant (reckless vs prudent, deliberate vs inadvertent) maps closely to this table — the useful axis is not "is there debt" but "did we choose it, and do we know what it costs."
How to measure it
- Count the workaround, not the ugliness. Debt shows up as a recurring tax: the extra step every engineer takes around a bad abstraction, the manual process instead of an automated one.
- Track it where work is already tracked. A backlog ticket describing the shortcut and its cost is more useful than a wiki page nobody reads.
- Attach a cost estimate, even a rough one. "Costs about two hours per sprint in workarounds" is more persuasive to a stakeholder than "this code is bad."
- Revisit the estimate periodically. Debt that cost nothing six months ago can compound as more code depends on the same shaky foundation.
Common mistakes
Calling every disagreement about code style "technical debt." This flattens a useful engineering concept into a vague complaint and makes it harder to get real debt prioritized.
Never quantifying the cost. "We should really fix this" loses every prioritization conversation against a feature with a measurable business impact. Attach a number, even an estimate.
Treating all debt as equally urgent. A shortcut in a rarely touched internal tool is not the same priority as one in the payment path. Rank by blast radius and how often the code is touched.
Letting debt accumulate silently. If nobody tracks it, it does not get scheduled. Put it in the same backlog as feature work, with the same visibility.
FAQ
Is technical debt always bad?
No. Deliberate debt taken on with a plan to repay is a normal, often correct tradeoff — it gets you real information from shipping faster than building the "perfect" version first.
Who decided that shortcuts in code count as debt?
Ward Cunningham introduced the metaphor in 1992, originally to describe the cost of shipping based on incomplete understanding of a problem, not to describe sloppy work.
How is technical debt different from a bug?
A bug is incorrect behavior. Technical debt is a design or implementation choice that is currently correct but costly to extend or maintain. Debt often causes bugs later, but the two are distinct.
Should technical debt block a release?
Rarely on its own. It is a planning input, something to schedule repayment for, not usually a release blocker unless it poses an immediate risk like a security gap or a scaling limit you are about to hit.
Where to go next
For the practical follow-up, see how to pay down technical debt in 2026 and refactoring legacy code, a safe process for 2026. If the debt in question involves an old system you are replacing rather than repairing, the strangler pattern for legacy migration in 2026 covers the incremental-replacement approach.