Pattern/Computing and Information/No. 1020

Technical Debt

Technical debt is the extra cost of later software changes caused by design or coding compromises. Ward Cunningham introduced the metaphor in 1992. In software engineering, it links the gains from early choices to the added work those choices create over time.

Also called Tech Debt

a pattern: watch for it

01You've seen this when…

  1. in life

    Your budgeting script has bank names scattered through several files. When one bank changes its export format, fixing the import also means repairing the charts and monthly totals.

  2. at work

    A developer adds a coupon feature. Checkout, invoices, and refunds each calculate discounts differently, so a small request turns into a week of tracing rules.

  3. out in the world

    A city needs to update its permit website for a new accessibility requirement. Years of custom form controls make each change require another round of repairs and testing.

02The idea

Software keeps a record of earlier decisions. A team duplicates a calculation, skips an automated test, or builds around an assumption it later outgrows. That choice can make the next release easier. Future releases inherit the consequences.

Cunningham’s financial metaphor separates two costs. The principal is the work needed to remove the compromise: consolidate the calculation, add the tests, or replace the outdated model. The interest is the extra work the compromise adds while it remains: updating several copies, checking behavior manually, or working around an awkward interface.

The interest arrives when someone touches the affected code. A shortcut in a feature that never changes may cost very little. The same shortcut in a heavily used pricing system can slow work every week.

This makes technical debt a planning concern. Shipping sooner can bring revenue, feedback, or a chance to test demand. The trade-off is whether that benefit outweighs the extra work expected later. As other features build on the original choice, path dependence can make repayment harder.

03Why it happens

  • The deadline has an owner. A launch date is visible and immediate. Future maintenance costs are spread across developers, support staff, and releases, so they receive less weight in today’s decision.
  • Understanding improves after delivery. Customers reveal missing cases, and developers learn which concepts belong together. Working code can preserve assumptions the team has already outgrown. Debt can accumulate through learning even when the original work was careful.
  • Local fixes spread their costs. Copying a rule into another module is quick. Keeping the copies consistent creates work across the system. Weak boundaries undermine separation of concerns, where each part has a distinct responsibility.
  • Repayment competes with visible features. A cleanup may produce few changes customers can see. If its benefit stays vague, another feature wins the budget. Meanwhile, each workaround gives the next developer another dependency to preserve.

04A worked example

Consider a fictional ticketing company preparing a group-booking launch. A shared pricing component would take four engineer-days to build. Copying the existing calculation into checkout, invoices, and refunds takes one day. The team chooses copying to meet the launch date.

What it looks like A sensible saving of three engineer-days. The feature works, customers can book, and the release goes ahead.

What’s actually going on The company soon starts changing group discounts every week. Each change requires someone to compare the three implementations, update them, and check that refunds still agree with invoices. The team estimates that this duplication adds two engineer-days of work each week. It also creates opportunities for inconsistent charges.

What would have helped Recording the duplication when it was introduced, with an owner and a review trigger. Once weekly pricing changes become routine, the economics change. Suppose consolidation, including tests, now takes six engineer-days. At the estimated rate of two extra days per week, that effort pays back in roughly three weeks. The calculation depends on continued pricing changes and accurate estimates; migration risks belong in the estimate too. If the feature were being retired next month, repayment would have a different case.

05How to spot it

06What to do about it

  • Describe the cost in ordinary work. Record the compromise, the tasks it slows, and a concrete example. A note that discount changes require three implementations is more useful than a general complaint about code quality.
  • Make the borrowing decision explicit. State what shipping sooner gains, what assumptions make the shortcut acceptable, and what event should prompt a review. A new customer, repeated changes, or an approaching upgrade can serve as a trigger.
  • Rank debt by expected exposure. Consider how often the affected code will change, how much extra work each change creates, and the consequences of mistakes. Include the opportunity cost of taking developers away from other work.
  • Repay in bounded pieces. Add tests around the behavior, isolate a responsibility, or consolidate one repeated rule. Useful modularity can reduce the number of places a change reaches. A sweeping rewrite needs its own business case and migration plan.
  • Check whether the surcharge shrinks. After repayment, compare similar changes: review effort, testing time, escaped defects, and delivery time. Adjust priorities using what actually improved.

Sometimes waiting has option value. A product experiment may soon settle which design is needed. In that case, keep the compromise contained and set a date to reconsider it.

07When it isn’t technical debt

Software requires ordinary upkeep. A new legal requirement, a changed customer need, or routine dependency maintenance can create work without exposing a costly earlier compromise. A bug describes incorrect behavior; technical debt describes extra future effort. They can overlap, and either can exist separately.

An ugly function can be cheap to live with if it rarely changes. An elegant framework can impose expensive restrictions on every new feature. The useful test is the work an earlier choice adds to likely future tasks.

The financial analogy also has limits. Technical debt has no fixed interest rate or repayment date. Its cost can rise suddenly, remain dormant, or disappear when a feature is retired.

08Roots

In his 1992 report on WyCash, Ward Cunningham described work on a financial portfolio management system built in Smalltalk. The financial setting supplied a fitting metaphor for a development problem: a team could deliver working software before its design fully expressed what it was learning about the domain.

Cunningham wrote, “Shipping first time code is like going into debt.” Early delivery could accelerate learning. Rewriting the code afterward would bring the design into line with that improved understanding. Leaving the gap in place made further development harder, much as interest consumes money available for other uses.

The phrase later expanded to cover deliberate shortcuts, missing tests, architectural constraints, and accumulated maintenance problems. Software-engineering researchers and practitioners developed ways to identify and prioritize these costs. That broader use made the metaphor useful to managers as well as programmers, while creating a recurring challenge: showing exactly which future work a particular debt item makes more expensive.

09How solid is this?

ContestedMixedUsefulEstablished

Practitioner interviews and software-engineering research document compromises that add later development and maintenance work. The metaphor covers several mechanisms, so repayment benefits and ongoing costs need local estimates; there is no universal interest rate.

10Connections

countered bycountered bycountered bycountered bycountered byleads toleads topart ofTechnical DebtChesterton’sFenceGall’s LawNot written yetSeparationof ConcernsModularityVia NegativaNot written yetBrittlenessNot written yetLock-InPath DependenceOpportunityCostOption Value

+ 1 more in the list

11Origin and sources

Ward Cunningham introduced the debt metaphor in his 1992 OOPSLA experience report on the WyCash portfolio management system.

  1. [1]Cunningham, W. (1992). The WyCash Portfolio Management System. OOPSLA '92 experience report.
  2. [2]Kruchten, P., Nord, R. L., & Ozkaya, I. (2012). Technical Debt: From Metaphor to Theory and Practice. IEEE Software, 29(6), 18–21.
  3. [3]Lim, E., Taksande, N., & Seaman, C. (2012). A Balancing Act: What Software Practitioners Have to Say about Technical Debt. IEEE Software, 29(6), 22–27.

Suggest an edit· Updated 2026-10-02