Overview
Cunningham's original metaphor was precise: shipping with a simplified design to learn faster is borrowing — sound leverage, provided you repay by folding what you learn back into the code. Today "tech debt" has blurred into meaning "any code we dislike", which makes it unmanageable. Restoring the distinction — deliberate trade-offs vs. accumulated cruft vs. plain recklessness — is what turns debt from a team lament into a portfolio you can actually manage.
Key points
- Fowler's quadrants give the vocabulary: deliberate–prudent ("ship now, we know the cost, ticket filed") is strategy; inadvertent–prudent ("now we know how we should have built it") is learning, unavoidable and healthy; deliberate–reckless ("no time for design") and inadvertent–reckless (didn't know better) are just damage. Only the first kind is honestly "debt taken on"; treat each kind differently.
- The interest is the point, not the principal: debt matters only where you pay interest — friction on code you actively change. Ugly-but-stable code in a corner nobody touches charges nothing; don't pay off debt that isn't billing you. Map debt against change frequency (hotspot analysis: churn × complexity) to find where the interest actually accrues.
- Make it visible or it doesn't exist: a debt registry (lightweight tickets, or ADR-style records of the shortcut and its assumed repayment — architecture documentation), named at estimation time ("this is the quick version; the real one costs X later"). Invisible debt gets denied by whoever didn't incur it.
- Repayment strategies, smallest first: the boy-scout rule and preparatory refactoring (refactoring techniques) fold repayment into feature work — invisible to planning, continuous, the default; dedicated capacity (a fixed slice of each cycle) for named medium items; the strangler-fig for structures too big to fix in place. The "stop everything and rewrite" project is the strategy of last resort — it pays compound interest on new debt while freezing delivery, and its second-system risk is well documented.
- Frame it in business terms or lose the argument: "this debt costs us N days per quarter and makes X class of features risky" gets capacity; "the code is ugly" never does. Defect rates, lead-time drag, and onboarding time are the debt metrics leadership can hear.
- Some debt should be taken: before product-market fit, before a deadline that matters, in code slated for deletion — the discipline is writing down the loan. A team with zero appetite for debt is over-engineering; a team that can't name its debts is defaulting.
- To explore: hotspot analysis tooling (CodeScene lineage), architecture fitness functions as debt tripwires, the "debt ceiling" working agreement.
Practice
- Debt registry sprint (source) — spend an hour on one module of a project you own: inventory its shortcuts as ADR-style debt records, each classified by Fowler quadrant with its assumed repayment; teaches "make it visible" by producing the artifact.
- Hotspot analysis on a real repo (source) — mine a repo's git log with code-maat, cross churn against complexity, and rank the hotspots; teaches finding where interest actually accrues — then check whether your gut agreed.
- Mikado method run (source) — attempt one over-sized refactoring naively, revert on every break, and grow the prerequisite graph until it lands as a sequence of safe steps; teaches structured repayment of debts too big for the boy-scout rule.
- Gilded Rose: a technical-debt workout (exercise) — the classic legacy-code kata run as a full debt-management cycle: characterize, refactor, extend, then write the business case; the substantial end-to-end drill.
Related
- Refactoring techniques — the repayment mechanics.
- Estimation & planning — where debt is incurred and where its interest surfaces.
- Code review — the checkpoint where shortcuts get named or waved through.
- Clean code — the asset side of the balance sheet.