Short answer
Technical debt is the future cost of shortcuts and ageing design in your software. Measure it by its interest, meaning slower delivery, incidents and risk in specific areas, not by code quality alone. Prioritise debt in code that changes often and causes pain, fund a steady share of capacity for it, and report it to the business as cost and risk.
- 2 - axes in the debt quadrant: reckless or prudent, deliberate or inadvertent
- 4 - kinds of debt, each needing a different response
- 3 - delivery metrics that reveal costly debt: lead time, fail rate, rework
- 1 - rule: pay down the debt that charges the most interest first
Technical debt is the gap between how your software is built today and how it would need to be built to change quickly and safely. Like a loan, it is sometimes worth taking on to ship sooner. The problem is the interest: every change in an indebted area costs more, fails more and carries more risk until the debt is repaid. Leaders need to manage it as a portfolio, not argue about it feature by feature.
Where the term comes from, and what it is not
Ward Cunningham coined the metaphor in a 1992 experience report: “Shipping first time code is like going into debt. A little debt speeds development so long as it is paid back promptly.” The danger, he warned, is debt that is never repaid. Three decades later the idea is the same, but the scale is not: most organisations now carry debt across dozens of services, cloud platforms, data pipelines and third-party dependencies.
It also helps to be clear about what technical debt is not. A bug is a defect in behaviour; debt is a property of the design that makes defects and changes more expensive. Legacy software is not automatically debt either: a stable system nobody needs to change charges little interest. Debt matters when the business needs to change something and the software resists.
The four kinds of technical debt
Martin Fowler’s technical debt quadrant is the most useful vocabulary for leaders, because it separates debt you chose from debt you fell into, and careful debt from careless debt.
DeliberateInadvertentPrudentTaken knowingly to hit a date, with a plan to repay itDiscovered later: the better design only became clear after buildingReckless“Quick and dirty” because the team believes it has no time for good designAccumulated without realising, often from missing skills or standards
Prudent debt is a normal part of building products and should be tracked like any other liability. Reckless debt is a management signal: it points to unrealistic deadlines, missing skills or a lack of engineering standards, and paying it down without fixing the cause only makes room for more.
Types of technical debt, with examples
The quadrant explains how debt arose. To decide what to do about it, leaders also need to know where it lives. These are the types of technical debt that show up most often in modern software estates:
TypeTypical exampleWhat it costs youCode debtDuplicated logic, very long functions, unclear namingSlower changes and more defects in that areaArchitecture debtA monolith where every change touches billing; tight coupling between servicesTeams block each other; small features need large releasesTest debtLittle automated testing, or a slow and flaky test suiteFear of change, manual regression and long release cyclesDependency and security debtUnsupported frameworks, outdated libraries, end-of-life runtimesSecurity exposure, painful upgrades, compliance findingsInfrastructure debtHand-built servers, no infrastructure as code, snowflake environmentsSlow recovery, inconsistent environments, cloud wasteData debtDuplicated customer records, undocumented schemas, brittle integrationsBad reporting, failed AI and analytics projectsKnowledge debtMissing documentation; one engineer who understands the payment systemKey-person risk and slow onboarding
Most real problems combine several types. An outdated framework (dependency debt) with no tests (test debt) in a module that every product team touches (architecture debt) is exactly the kind of hotspot that deserves to be at the top of the list.
What causes technical debt
Paying down debt without addressing its causes is like clearing a credit card while still spending on it. The common causes are organisational as much as technical:
- **Deadline pressure without a repayment plan. **Shortcuts are taken to hit a date, and the follow-up work never makes it onto the roadmap.
- **Changing requirements. **The product outgrows the design it started with, which is normal and should be expected.
- **Skills and standards gaps. **Teams without code review, shared standards or experienced engineers create reckless debt without noticing.
- **Neglected upgrades. **Frameworks, libraries and runtimes age quietly until an upgrade becomes a project in its own right.
- **Team turnover. **Knowledge leaves with people, and code nobody understands becomes code nobody dares change.
- **Incentives that reward only features. **If roadmaps and performance reviews count only new features, maintenance always loses.
Why “we need a rewrite” is the wrong conversation
When debt becomes painful, engineers often propose a rewrite. Rewrites are expensive, risky and frequently recreate the same problems in newer technology. A better question is which parts of the system charge the most interest, and what the cheapest way is to reduce that interest. Sometimes the answer is targeted refactoring; sometimes it is replacing one component; occasionally it is a staged rebuild. Our modernise or replace framework covers that decision in detail.
How to measure the interest you are paying
Code-quality scores alone do not tell you what debt costs. Measure the effects in each product area or service, and the debt that matters becomes visible:
- Change lead time and change fail rate for that area, compared with the rest of the codebase.
- Deployment rework rate: how much delivery is unplanned work triggered by incidents.
- Incidents and support tickets traced to the area.
- Engineer time spent on workarounds, manual steps or fragile tests, from team estimates.
- Risk: unsupported frameworks, security findings, single points of knowledge.
These are the same signals DORA uses for delivery performance, so if you already track DORA metrics, you can break them down by service and see where debt slows you most.
Technical debt ratio and code-quality tools
Static analysis tools put a number on code-level debt. SonarQube, for example, reports a technical debt ratio: the estimated cost to fix maintainability issues relative to the estimated cost of developing the code. Its default maintainability rating gives an A at 5% or below, B up to 10%, C up to 20%, D up to 50% and E above that.
These numbers are useful for spotting trends and for stopping new debt at the door, for example by failing a build when new code drops below a rating. They are a poor guide to business priority on their own, because they measure how code looks, not how much it slows the company down. Use them alongside the delivery and incident signals above, not instead of them.
A simple scoring model to prioritise debt
FactorQuestionScore 1–5InterestHow much does this debt slow or break changes today?Higher = more painChange frequencyHow often do we change this area?Higher = more oftenRiskCould it cause a security incident, outage or compliance failure?Higher = more riskCost to fixHow much effort does paying it down take?Higher = more expensive
Rank items by interest × change frequency × risk, divided by cost to fix. Debt in code that changes every week and causes incidents rises to the top; old code nobody touches drops down, however ugly it looks. Review the ranking quarterly, because both the product and the debt change.
Keep a technical debt register
Debt that lives only in engineers’ heads cannot be prioritised or funded. A technical debt register, kept in the same backlog tool as the rest of the work, turns complaints into decisions. Each entry needs only a few fields:
- **Area and type: **which service or module, and which type of debt from the table above.
- **Evidence of interest: **lead time, incidents, workaround hours or risk findings that show what it costs today.
- **Score: **the interest, change frequency, risk and cost-to-fix ratings from the scoring model.
- **Owner: **the team responsible for the area.
- **Proposed fix and size: **targeted refactor, component replacement or upgrade, with a rough estimate.
Review the register in quarterly planning, alongside the product roadmap. That is where the trade-offs between features and paydown should be made, openly, by the people who own both.
How to fund paydown
If you are unsure where your largest risks sit, an independent software architecture review gives you an evidence-based debt map and a phased plan.
How much time should go to technical debt?
There is no universal percentage, and any figure quoted as a rule should be treated with caution. Many teams reserve somewhere between a tenth and a fifth of their capacity for debt and maintenance, but the right share depends on how much interest you are paying. A young product with a healthy codebase needs less; a platform with rising lead times, repeat incidents and unsupported dependencies needs more, at least for a while.
A practical approach is to start with a fixed allocation, make it visible in planning, and adjust it each quarter based on the signals in the register. If lead time and incidents in the worst areas are falling, the allocation is working. If they are flat or rising, it is too small or spent on the wrong items. What matters most is that the allocation is protected: capacity that disappears whenever a deadline looms is not an allocation at all.
Technical debt in agile and Scrum teams
Agile teams do not avoid technical debt; short iterations can create it faster if every sprint is filled with features. The fix is to make debt work visible in the same backlog as everything else, size it like any other item, and let the product owner see the trade-off. Debt items written in business terms (“reduce checkout release time from two days to two hours”) compete fairly with features; items written as “clean up the order service” rarely get picked.
Retrospectives are a good early-warning system. When a team keeps naming the same module as the reason a sprint slipped, that module belongs on the register with evidence attached.
How to reduce technical debt without stopping delivery
The most effective debt reduction happens alongside feature work, not instead of it. These practices let teams reduce technical debt while still shipping:
- **Refactor where you work. **When a feature touches an indebted area, leave the code better than you found it, and include the time in the estimate.
- **Write tests before changing risky code. **Characterisation tests capture current behaviour, so the team can refactor without fear of breaking it.
- **Replace in slices with the strangler fig pattern. **Route one capability at a time to a new component until the old one can be switched off, rather than betting on a big-bang rewrite.
- **Upgrade on a schedule. **Small, regular dependency and runtime upgrades are cheap; a five-year jump is a project.
- **Make quality part of “done”. **Code review, automated tests and quality gates on new code stop most reckless debt from being created at all.
- **Delete what nobody uses. **Retiring unused features, endpoints and integrations is the cheapest paydown there is.
AI-generated code and the next wave of debt
AI coding assistants let teams produce code faster than ever. That speed is valuable, but it also makes it easier to add code that nobody fully understands, duplicates existing logic or skips the team’s conventions. Without review standards, more output can simply mean debt accumulating faster.
The answer is not to ban the tools; it is to apply the same discipline to AI-written code as to any other: code review by someone who understands it, tests that prove its behaviour, and quality gates that catch duplication and complexity before merge. Track the debt signals above by area, and you will see quickly whether faster delivery is turning into slower change.
How to talk about technical debt with the board
Boards do not need code detail. They need to know which products are slower or riskier to change, what that costs, and what it will take to fix. Frame debt as a business liability with a cost of carry: “Changes to billing take three times longer than elsewhere and caused four incidents last quarter; a two-quarter investment reduces both.” The hidden cost of legacy systems makes the same case at the level of the whole economy.
Questions to ask your engineering leaders
Is our technical debt under control?
- Which three areas of our software charge the most interest, and how do we know?
- How do lead time and failure rates in those areas compare with the rest of the system?
- What share of capacity goes to debt today, and is it enough to reduce it?
- Which debt was reckless, and what are we changing so it does not recur?
- What will be measurably better in two quarters if we fund the top items?
Engineering leadership
Need a debt map the business can fund?
We measure where technical debt costs you most, rank it with your teams and turn it into a phased, costed plan your board can approve.
Sources
- Technical Debt Quadrant (Martin Fowler)
- DORA software delivery performance metrics (dora.dev)
- The WyCash Portfolio Management System (Ward Cunningham, OOPSLA 1992)
- Strangler Fig Application (Martin Fowler)
- SonarQube metrics: technical debt ratio and maintainability rating (Sonar documentation)
Originally published at phpscientist.com.
Top comments (0)