Every working software system contains decisions that were right at the time and are expensive now. A database schema designed for one country, a front end built before mobile mattered, a deployment process that only one person understands. None of these is unusual. The debt becomes a problem when it is invisible, unmanaged and paid for in late nights and lost opportunities.
This guide is written for the person who signs the technology budget, not only for engineers. It explains what technical debt actually costs, how to measure it without a microscope and how to repay it without stopping the roadmap.
Debt is a financing decision
Sometimes taking on debt is correct. Shipping a simple version to learn from customers is often smarter than building a perfect system nobody wants. The mistake is pretending the debt is free, or forgetting that it has an interest rate.
Deliberate, documented debt is manageable: "we are using a manual export for this quarter; we will automate it before the volume exceeds 500 records a month." Accidental debt is the dangerous kind: nobody knows it exists until it breaks.
The four kinds of technical debt
| Type | Looks like | Business symptom |
|---|---|---|
| Code debt | Duplicated logic, missing tests, unclear naming | Small changes take longer than expected |
| Architecture debt | Tight coupling, no clear boundaries, workarounds on workarounds | New features require changes in many places |
| Infrastructure debt | Manual deployments, unpatched servers, no staging | Releases are risky and incidents are common |
| Knowledge debt | Undocumented systems, one-person dependencies | People are afraid to change things; holidays are stressful |
Most organisations have all four, but the business feels them differently. Code debt slows feature work. Architecture debt limits what is possible. Infrastructure debt creates outages. Knowledge debt creates key-person risk and makes every resignation a crisis.
How to measure the cost
You do not need a perfect metric. Four indicators are enough to start a budget conversation:
- Cycle time: how long a small, well-understood change takes from ticket to production. Track the median, not the average.
- Change failure rate: the share of releases that cause an incident or require a rollback.
- Incident minutes: total customer-facing downtime per month, and the internal hours spent recovering.
- Dependency age: how far behind critical libraries and runtimes are, and how many have no maintained upgrade path.
Translate at least one of these into money. If a team spends 30% of its time on workarounds, that is 30% of payroll unavailable for new revenue. If an outage costs a known amount per hour, incident minutes become a financial figure.
Prioritise by impact, not by ugliness
Engineers often want to fix the code that annoys them most. The business needs the debt that costs the most. Score each item on four dimensions:
- Frequency: how often does this slow down or break work?
- Impact: what happens when it fails — a delay, a security issue, a lost customer?
- Spread: how many teams or systems does it affect?
- Trend: is it getting worse quickly?
High-frequency, high-impact, spreading debt goes first. Low-impact cosmetic debt can wait. A useful rule: if a debt item has not caused a delay or incident in a year and is not on the path of planned work, it is probably not a priority.
Five ways to repay without stopping the roadmap
1. The boy scout rule. When you touch a file or module for a feature, leave it slightly better: add the missing test, rename the confusing function, remove the dead branch. Small, continuous improvements compound.
2. Reserve capacity. Allocate 15–20% of each sprint to debt that has a written business rationale. Protect it like any other commitment; otherwise it becomes the first thing cut.
3. Bundle with features. When a feature requires changes in a messy area, include the cleanup in the estimate. The incremental cost is smaller than a dedicated refactoring project later.
4. Dedicated repayment sprints. For a major architectural problem, a focused two-to-four-week effort with a clear exit criterion can be worth the pause. Do not run them for vague "cleanup"; define the outcome.
5. Strangler pattern. Instead of rewriting a legacy system, put a new interface in front of it and migrate one capability at a time. The old system shrinks until it can be switched off. This is slower than a rewrite on paper and much faster in practice.
Rewrite is usually the wrong answer
Rewrites are attractive because the current system is painful and the new one is imaginary. They are also where teams lose years. The old system keeps changing while the new one is built, requirements are rediscovered, and the last 10% takes most of the time.
Rewrite only when the current system cannot support the business at all, the team has exhausted incremental options and there is a credible plan to run both in parallel. Otherwise, improve the seams: add tests, isolate the worst module, replace one capability at a time.
A 90-day plan
- Days 1–15: Build a debt register with the four types and a business impact note for each item. Do not list everything; focus on the top twenty.
- Days 16–30: Measure cycle time and change failure rate for one team. Establish a baseline.
- Days 31–60: Pick two items: one quick win that removes a frequent annoyance and one structural fix that reduces risk. Assign owners and success criteria.
- Days 61–90: Ship both, measure again and publish the result. Add a standing 15% capacity allocation for the next quarter.
Publish the register where the business can see it, with plain-language descriptions. "The billing service has no automated tests, so every pricing change requires two days of manual checks" is a sentence a product owner can prioritise. "Refactor the invoice module" is not.
The culture problem
Debt grows when teams are rewarded only for shipping and never for keeping the system changeable. If every sprint is full and every estimate is squeezed, the only variable left is quality. Eventually the system enforces the trade-off for you.
Leaders can change the incentive with three small moves: ask about operational health in the same review as feature delivery, make the debt register a standing agenda item and protect the cleanup capacity when deadlines tighten. None of these requires a new methodology.
The bottom line
Technical debt is a normal part of building software. The goal is not zero debt; it is debt you chose, understand and can afford. Measure the interest, prioritise by business impact and repay in small, continuous payments. A system that is easy to change is a competitive advantage that compounds quietly.
Start with one metric and one item this month. The goal is not a perfect codebase; it is a team that can keep shipping without paying more each quarter for the same change.


