Technical debt is the accumulated cost of shortcuts, deferred refactors, and design decisions that made sense at the time but now slow the team down.
Technical debt is the accumulated future cost of code, architecture, and infrastructure decisions that were expedient at the time and are now slowing the team down. Ward Cunningham coined the metaphor in 1992, and it mostly holds: like financial debt, some tech debt is strategic (ship now, refactor later), some is reckless (shortcuts that were never going to hold up), and all of it accrues interest in the form of slower feature delivery, longer onboarding, and more bugs.
Not all debt is the same. (1) Deliberate & prudent — 'we shipped the MVP with hardcoded config; we'll refactor when we have three customers.' (2) Deliberate & reckless — 'we don't have time to write tests, we'll add them later' (spoiler: nobody does). (3) Inadvertent & prudent — 'now that we understand the domain, we'd design this differently.' (4) Inadvertent & reckless — 'we didn't know what we were doing.' Only the first and third categories are worth taking on strategically; the other two are just poor engineering hiding behind metaphor.
Debt only matters when it costs you. Signals the interest is real: recurring bugs in the same subsystem, features that used to take days now take weeks, new hires taking months to become productive, deploys that require a specific person to be online, incidents that are hard to diagnose because the code path is unclear. If none of these hurt, the debt is dormant — leave it alone. If two or more hurt regularly, the interest payment has crossed the threshold where paydown is cheaper than continued interest.
Three approaches. (a) Dedicated refactor sprints — 1-2 weeks per quarter of pure debt work. Simple, but often gets deferred when a customer commit lands. (b) Continuous 20% — every engineer spends one day a week on debt paydown adjacent to their current feature. More sustainable, harder to measure. (c) Opportunistic — refactor as you touch the code, boy-scout-rule style. Works for small debt, fails for structural problems that span systems. Most healthy teams use a mix: opportunistic by default, dedicated sprints for structural debt, continuous 20% during PMF search when the codebase is churning fastest.
Every codebase eventually reaches a point where a full rewrite feels attractive. Almost every full rewrite takes 3-5x longer than estimated, misses features the original had, and introduces its own new debt. The exceptions are rare: fundamental architectural mismatch (monolith → services when you truly need it), platform obsolescence (Flash, IE-only frameworks), or acquired codebases with unrecoverable design. Default answer: incremental refactor, strangler-fig migrations, boundary-by-boundary. Reserve full rewrites for the rare case where the old codebase's shape actively prevents the new business.
Founders and boards don't care about debt as engineers describe it. Translate: 'this feature will take 6 weeks instead of 2 because of X'; 'we're seeing 3x incident frequency in this subsystem'; 'onboarding time doubled since we shipped Y.' Show cost in shipping velocity, not lines of code. When paydown work is justified in business terms, it gets funded; when it's justified as 'we want to refactor,' it doesn't.
Investor directory · Fundraising library · Articles A–Z · Company funding database