Logo von nextlevels
DEEN
Request a project

Technical debt

Last updated on

In short

Technical debt (German: technische Schuld) refers to the sum of the future extra effort that arises because a software solution was, consciously or unconsciously, built more simply, faster or less cleanly at the time of its creation than would have been appropriate for its long-term further development.

The term comes from Ward Cunningham, who introduced it in 1992 in an experience report at the OOPSLA conference. Cunningham compared unfinished code with a loan: you can deliver functionality earlier by borrowing time, but every further change to this code then costs a little more, and this surcharge is the interest. As long as the debt is repaid, the loan is a legitimate tool. If it is never repaid, the interest eventually eats up the entire development capacity.

Important is the clarification Cunningham himself made later: the metaphor does not mean bad code that arises from ignorance. It means code that reflects a correct understanding of the domain at the time, while that understanding has since evolved. The debt consists in the gap between what the team knows about the problem today and what the software says about it.

How technical debt arises

In practice technical debt is fed from very different sources. Martin Fowler proposed a four-quadrant scheme for this that combines two axes: deliberate versus inadvertent, and prudent versus reckless.

  • Deliberate and prudent: "We'll ship now and clean up in the next sprint." A calculated decision with a known price: the normal case in healthy teams.
  • Deliberate and reckless: "We don't have time for clean design." The decision is made with eyes open, but without a repayment plan.
  • Inadvertent and prudent: "Now that the system is running, we can see how we should have cut it." This form is unavoidable and is what Cunningham actually meant in his original sense.
  • Inadvertent and reckless: "What is layering?" A lack of craft that only becomes visible when the system can no longer be controlled.

Across this, debt can be distinguished by the level affected, and for budget decisions this distinction is usually more useful than the motive.

TypeTypical appearanceRepayment effort
Code debtDuplicated logic, overlong methods, unclear naminglow to medium, locally limited
Architectural debtMissing module boundaries, circular dependencies, a monolith without a cuthigh, often only possible step by step
Test debtNo or unreliable automated tests, slow test suitesmedium, pays off fastest
Documentation debtOutdated interface descriptions, undocumented operating assumptionslow, but chronically neglected
Infrastructure debtManual deployments, unpatched runtime environments, legacy versionsmedium to high, often combined with a security risk

The interest mechanism

The core of the metaphor is not the debt itself but its interest. The interest is the additional effort that every future change in the burdened area costs: longer familiarisation, more manual testing, more coordination, more errors after the release. Two properties make it dangerous.

First, it is proportional to the frequency of change. A badly written module that nobody has touched for five years costs practically nothing. The same module in the checkout of an online shop, where something is changed every other week, costs permanently. That is why the obvious prioritisation is not "where is the code worst" but "where does bad code meet a high rate of change". This intersection is often determined using version control history and complexity metrics together.

Second, the interest has a cumulative effect on the speed of change. If every change takes longer, the number of changes per unit of time falls, the capacity available for clean-up work shrinks, and the debt grows further. Teams describe the final stage as a state in which even trivial adjustments take weeks and every release produces new outages.

How technical debt can be measured

Technical debt is not a physical quantity, but there are established approximations. The most widespread work with static code analysis. Tools such as SonarQube estimate a remediation effort in person-time on the basis of the SQALE method and relate it to the estimated effort of rewriting the system completely. A maintainability rating from A to E is derived from this ratio. The absolute figure should be treated with caution: it is based on flat-rate effort assumptions per rule violation. As a trend indicator over months it is nevertheless useful: what matters is whether the curve rises or falls.

In addition, delivery and operating metrics provide a picture that decision-makers often understand better than any code metric. The metrics established in the DORA research programme, deployment frequency, lead time for changes, change failure rate and time to restore, do not measure the code but its consequences. A permanently high change failure rate, i.e. a high share of releases that lead to disruptions, is a reliable symptom of missing investment in tests and architecture.

  • Code metrics: cyclomatic complexity, degree of duplication, test coverage, rule violations per thousand lines.
  • History metrics: frequency of change per file, number of developers per module, age of the oldest open dependency updates.
  • Impact metrics: change failure rate, lead time to production, share of unplanned work in the sprint.

Repayment strategies

Most technical debt is never paid down by one big project but by continuous small payments. Three approaches have become established.

Refactoring budget. A fixed share of development capacity, in practice often between ten and twenty per cent, is reserved and not negotiated against features. The advantage lies less in the amount than in the reliability: a budget that is the first thing cut under every deadline pressure does not in fact exist.

Boy scout rule. The rule popularised by Robert C. Martin says to leave every area of code you touch a little cleaner than you found it. The effect is that repayment happens exactly where the interest accrues, in the areas with a high frequency of change. It only works with reliable automated tests, because otherwise every clean-up is a risk.

Strangler fig pattern. For architectural debt that cannot be fixed locally, Martin Fowler described this pattern: a new system grows around the old one by intercepting individual functional areas one after the other and serving them in the new build, until the legacy system has no tasks left and can be switched off. Compared with a complete greenfield redevelopment, this has the advantage that the business remains operational throughout and every step can be reversed individually.

Real-world example: migrating from Shopware 5 to Shopware 6

A tangible example from e-commerce is the version jump from Shopware 5 to Shopware 6. Shopware 5 is based on a different technical foundation from Shopware 6, which is why custom extensions cannot simply be carried over but have to be redeveloped. Merchants who for years made adjustments directly in the template or in plugin overrides instead of using the intended extension points face exactly the accumulated bill in the migration: every unclean adjustment is now an item in the migration budget. Those who worked along the official extension mechanisms, on the other hand, migrate considerably more cheaply. In both cases the debt was taken on; only in the second case was it repaid continuously.

Technical debt and AI-generated code

With the widespread use of AI assistants in software development, the discussion has gained a new dimension. Generated code suggestions are syntactically clean and locally plausible but are created without a complete picture of the system architecture. Typical patterns that follow: duplicated helper functions instead of reuse, solutions that bypass existing abstractions, and code that nobody in the team has fully understood.

The decisive difference from classic debt is the pace. Code is created faster than the understanding of it, and review capacity becomes the bottleneck. The established remedies do not change as a result; they just become more important: mandatory code reviews by people, automated quality gates in the build pipeline and the rule that nobody takes code into production that they cannot explain.

Distinction and common misconceptions

Technical debt is not the same as bugs. A bug is wrong behaviour; technical debt is correct behaviour that is expensive to change. Nor is it the same as legacy software: an old system can be cleanly structured and easy to maintain, while a six-month-old one can just as well be unmanageable.

A second misconception is equating it with sloppiness. The metaphor was coined explicitly to make a rational decision describable, namely to deliver earlier and pay for it later. It loses its meaning when it becomes a catch-all for everything you do not like about the code.

Third, zero debt is not a sensible goal. A team that works out every decision to perfection delivers too late and learns too little about actual demand. The right business question is not "how do we avoid debt" but "which debt do we take on deliberately, at what interest, and when do we repay it".

Relevance for decision-makers in SMEs

For management and business departments, technical debt is relevant above all because it limits the company's ability to react. It is rarely visible as an item, but as a subordinate clause: a new payment method cannot be connected at short notice. An additional sales channel requires a project instead of a configuration. A legal requirement with a fixed deadline gets tight.

Three questions help to assess the state without technical depth: how long does it take from the final decision to the change in production? What percentage of development time flows into unplanned work? And how often does a release lead to a disruption? If these values worsen over several quarters, the interest rate is too high, regardless of what individual code metrics say.

When choosing service providers, how they handle the topic is a quality signal. Those who show refactoring shares in the quotation, treat test coverage as part of the delivery and document architectural decisions sell more expensively in the short term and more cheaply in the long term.

Outlook

Two developments are foreseeably shaping the topic. On the one hand, dependency and infrastructure debt is moving more into focus through the regulation of supply chains: outdated components are no longer just a maintenance issue but increasingly a compliance issue. On the other hand, AI-supported development is shifting the bottleneck from code generation to code understanding. In parallel, tools are emerging that use the same technology in the opposite direction: automated dependency updates, test generation for untested legacy code, suggestions for architectural refactorings. Which side prevails is decided not by the technology but by whether organisations treat repayment as a fixed part of their capacity planning.

Frequently asked questions

Is technical debt always bad?

No. Debt taken on deliberately with a repayment plan is a legitimate means of getting to market earlier or testing an assumption faster. It becomes problematic when it accumulates unnoticed or is never paid back.

How much capacity should a team reserve for repayment?

There is no universally valid value. A fixed double-digit percentage of sprint capacity is common. More important than the amount is that the share is not the first thing cut under every deadline pressure.

Can technical debt be quantified in euros?

Only approximately. Tools such as SonarQube estimate a remediation effort in person-time that can be converted into costs. However, this figure is based on flat-rate assumptions and is more suitable as a trend indicator than for an investment calculation.

Is a complete rebuild the better solution?

Rarely. A greenfield redevelopment ties up capacity for a long time without delivering business value and often reproduces old mistakes in new technology. Gradual replacement following the strangler fig pattern is less risky in most cases.

Who decides on repayment?

Prioritisation belongs in the same round that also decides on features. Development teams provide the professional assessment of which areas cause the highest interest; product or business management decides on the distribution of capacity.

Further information on the origin of the metaphor can be found in the Wikipedia overview of technical debt.

Changelog

  1. · Created · Jan Schumann