Technical Debt Defined

Software | . Edited . 8 min read (1984 words).

Technical debt is one of the most persistent and useful metaphors in software engineering and it is also one of the least clearly defined. This post sets out a clear, rigorous definition aligned with current research and practice.


Money flying away from the bank

Topics:

Executive summary

Technical debt is not an objective property of code. It is a management concept: anything that unnecessarily slows a team or increases risk, until it is repaid. It is one of the most important levers for improving software delivery performance and sits at the intersection of engineering and management.

Managers should care about technical debt because it reduces a team’s value creation capacity. Engineers should care about it because it provides a shared language with management and a framework for discussing quality and productivity.

Importantly, technical debt is not a trade-off between speed and quality and is context-dependent. What slows one team down may at times speed another up.


Origin and confusion

The phrase technical debt was coined by Ward Cunningham in 1992. He introduced it as a metaphor to explain why refactoring matters:

“Shipping first time code is like going into debt. A little debt speeds development so long as it is paid back promptly with a rewrite… The danger occurs when the debt is not repaid. Every minute spent on not-quite-right code counts as interest on that debt. Entire engineering organizations can be brought to a stand-still under the debt load of an unconsolidated implementation, object-oriented or otherwise.” — Ward Cunningham

The metaphor was powerful. It gave engineers a way to explain hidden costs: moving fast without cleaning up creates obligations that must eventually be repaid. Otherwise the team pays ‘interest’ in the form of slower change and higher risk.

Over time the metaphor has been stretched. Some equate technical debt with bad code. Others treat it as a deliberate trade-off where cutting corners buys short-term speed. Both interpretations miss the point.

The idea of a trade-off between speed and quality is especially misleading. Decades of research, most notably the Accelerate and DORA studies1, show that speed and quality are not in conflict. Teams with higher internal quality – automated testing, good architecture, disciplined CI/CD – deliver both faster and more reliably. What looks like acceleration when quality is neglected is usually an illusion: the liquidation of future capacity, not a genuine loan.

Another misconception is to treat technical debt as an objective property of code. This invites attempts to measure it directly and critiques that it cannot be measured. In reality, technical debt is a management concept. It exists only in the context of a team’s ability to deliver change.

The origin remains important, but the concept requires refinement. By keeping Cunningham’s insight while aligning it with modern evidence, we can define technical debt in a way that is both clear and useful today.

Scope and domain

Technical debt belongs to software engineering and the delivery of change. Other forms of ‘debt’ – design debt, data debt, product debt – are useful extensions, but they are derivatives of the original metaphor.

This definition is deliberately limited in scope. It excludes runtime operations, ITIL processes, customer support and business obligations. Other disciplines have their own concepts for describing liabilities or may extend this one where appropriate. Software development and DevOps practices are both firmly included, as they directly affect a team’s ability to deliver change.

SRE practices overlap with the delivery of software change, but not all SRE concerns are in scope for technical debt (for example incident management).

By keeping the anchor in software change, we avoid diluting the term and preserve clarity by focusing on its primary domain. Sometimes, it can be useful to talk about code debt, process debt, test debt and similar subcategories.

Debt ≠ Loan: the financial analogy

In finance and law, debt means any liability that must be repaid. It does not imply a loan, nor does it guarantee an initial benefit. Debt is simply an obligation that reduces future capacity until it is cleared.

Two dimensions matter. On the balance sheet, debt appears as a liability – the principal. On the income statement, it shows up as drag – the interest. Both limit what an organisation can do with its resources.

The same holds in software. The origin of the debt is irrelevant. It may be messy code, a fragile test suite, weak CI/CD pipelines, a brittle process, a changing technical environment or accidental complexity. Whether intentional or not, the effect is the same: the team’s future capacity to deliver value is impaired until the liability is repaid.

The key point is this: technical debt is not about how it was created, but about how it constrains sustainable delivery. It does not require any upfront gains.

The definition

The definition is:

Technical debt is anything that reduces a team’s sustainable, risk-adjusted rate of value delivery through software changes, until it is repaid.

Each part of the definition matters. Anything signals that code, tooling, process and organisation all qualify. Team reminds us that debt is measured in a social context, not in abstract code. Sustainable rules out bursts that burn people out or collapse later. Risk-adjusted means apparent speed without reliability does not count. Value delivery through software changes anchors the scope. Until it is repaid underlines that liabilities can be cleared, restoring capacity.

Value delivery through change

In management terms, technical debt reduces productivity — the rate at which a fixed team generates value. In software, this means a reduction in the sustainable rate at which a team delivers business value through changes to software.

This framing makes technical debt inherently team-dependent: what slows one team may not slow another. In principle, if we could measure software productivity precisely, we could also estimate technical debt. In practice, productivity in software is difficult to measure, which is why the concept remains qualitative.

While business value itself is difficult to measure directly, the DORA metrics provide strong proxies. They track the rate and stability of software changes, which correlate closely with a team’s delivery capacity, even if they do not capture business impact in full.

Short bursts of activity are not true productivity. They create the illusion of progress while usually eroding future capacity. What matters is the sustainable rate of delivery over time — that is what technical debt constrains, and repayment restores.

Risk adjustment: the missing piece

In finance, returns are judged only after adjusting for risk. The same principle applies to software. Raw speed is meaningless if it carries hidden fragility.

Cutting corners can hurt in three ways. It can slow a team down directly through rework and inefficiency. It can lower the quality of what is delivered – reducing the value created. Finally, it can introduce technical risk – bugs, outages, security flaws or reputational damage – that may or may not materialise, but remain liabilities and discount the value delivered. Shipping a quick prototype without tests is the epitome of this false productivity: it looks fast, but it both delivers less value and carries heavy risk.

Real productivity comes from practices that raise sustainable capacity and lower risk: automated testing, good design, stable CI/CD pipelines and disciplined refactoring. These reduce risk and increase the steady rate of reliable value delivery over time.

By adjusting for risk, we avoid the trap of equating technical risk taking for increased productivity if the risk happens to pay off. That is a gamble and counts as a form of technical debt until the risk is resolved.

Context-dependent – not relativist

Technical debt is not an objective property of code, but neither is it purely a matter of opinion. Its impact depends on the context of the team and the work. A design that is manageable for a team of Linux kernel developers may be completely inappropriate for a team of Java Spring Boot developers, or vice versa.

This makes technical debt context-dependent – but not relativist. In principle, its effect on productivity could be measured, even if in practice it usually cannot. It is a matter of estimation rather than opinion or pure preference. The drag is real for the team experiencing it and is no less real than other essential management concerns.

Technical debt is inevitable

Technical debt is not a sign of failure. It is expected, normal and inevitable in any evolving system.

Like dust in a house, it accumulates as a natural by-product of activity. You are not a bad engineer for having it, just as you are not a bad person for needing to vacuum.

Debt can be managed and reduced, but it cannot be eliminated entirely. The goal is not to avoid it altogether, but to keep it under control so that it never overwhelms the team’s ability to deliver change.

Continuous repayment is essential

Technical debt is inevitable, but it must not be ignored. Repayment is essential and should be continuous.

The best teams fold it into daily work: refactoring as part of feature development, automating repetitive tasks, strengthening pipelines and stabilising processes. Large ‘cleanup projects’ are usually a sign that repayment has been neglected for too long.

A reasonable rule of thumb is to spend about 20% of engineering time on debt repayment each sprint or release cycle. In my experience this strikes the right balance: enough to keep debt under control without paralysing feature work. This assumes, of course, that new features already incorporate a degree of cleanup and refactoring as part of normal work.

Good modular design makes continuous repayment easier. By isolating complexity behind clear boundaries – as in Module-First Development – debt can be repaid locally and incrementally without disrupting the whole system.

Managers should care

Technical debt is not an engineer’s excuse for polishing code. It is a real liability – a drag on a team’s capacity to create business value.

In financial terms, refactoring, automation and process improvement are the equivalent of debt service. They do not add new features directly, but they restore capacity for future delivery. Ignoring this repayment is like skipping interest payments: the liability grows until it cripples performance.

Not every item engineers label as ’technical debt’ delivers the same return. Some fixes are marginal; others transform capacity. What constitutes debt – and whether it is worth repaying now – depends on the future roadmap and strategic context. A system that will be heavily extended next quarter may justify immediate cleanup, while one being phased out may not.

The role of management is not to second-guess every detail, but to maintain an ongoing dialogue with engineers about which debts matter most. By framing technical debt as a balance-sheet item, managers and engineers gain a shared language. Together they can prioritise the debt with the highest ROI, empower teams to act without micromanagement by providing proper context, and ensure that technical investments maximise business value and risk reduction.

Managing technical debt is managing delivery capacity — and in competitive markets, delivery capacity can contribute to competitive advantage.

Conclusion

Cunningham’s metaphor was powerful, yet incomplete. It gave us a language to speak about hidden costs, yet also left room for confusion. Decades of research, most notably DORA, show that speed and quality reinforce each other rather than trade off.

Refining the concept gives us clarity. With a precise definition, managers and engineers can reduce misunderstanding, align on what really constrains delivery capacity and manage technical debt as seriously as any other liability.

Debt is normal. It is not shameful. However, like any liability it must be managed – and clarity about what it means is the first step.