Skip to content
Muhammet Şafak
tr
3 min read

Which Technical Debt You Pay, Which You Live With

Not all technical debt deserves paying off. Separating debt that charges interest from debt that sits quietly, and spending a limited budget where it counts.

TL;DR

What makes technical debt bad is not the principal but the interest: debt in code you touch often and that slows every change gets paid, while ugly code that works and that nobody touches is carried where it stands. Sorting debt by how bad it is and how often it is touched points the limited refactoring budget at the debt that actually charges interest.

Cast-iron two-pan balance scale standing on a gray workshop surface, seen from the front

A backlog had two hundred “technical debt” tickets. The team carried them like a moral failing: “we have to pay all of these off.” Yet most of those two hundred tickets would never charge a single cent of interest over their entire lifetime.

Technical debt is not a matter of guilt; it is a matter of accounting. And not every debt deserves to be paid off.

Technical debt is a matter of accounting

The most important part of the debt metaphor is usually skipped: interest. What makes a real debt bad is not the principal; it is the interest.

The same goes for technical debt. Some debts charge interest: they slow you down every time you touch them, make every change harder, eat time every week. Other debts just sit there — they are ugly, but they cost you nothing. Treating the two as the same thing means spending a limited refactor budget in the wrong place.

Debt that charges interest

The debt that deserves to be paid off is the kind that charges interest:

  • A hot code region touched several times a week slows down every change because it is messy.
  • A fragile area has no tests around it and regularly blows up in production.
  • An abstraction was drawn wrong and every new feature has to wrestle with it.

What these have in common: their cost is paid over and over. Closing this debt makes every future change cheaper — the investment pays back.

Debt with no interest

Now the other extreme: ugly but working code in a module no one touches. It hasn’t changed in three years and probably won’t change for three more.

“Paying off” this debt — that is, refactoring it — means spending budget for zero return. Worse, touching working code carries the risk of new bugs. Debt with no interest isn’t paid off; it is carried where it sits.

Classifying debt

A practical framework places each debt on two axes: how bad it is × how often it’s touched.

  • Very bad + touched often → pay it off now. The interest is high.
  • Slightly bad + touched often → fix it as you get the chance, while you’re in there.
  • Very bad + rarely touched → document it, contain it, but don’t rush.
  • Slightly bad + rarely touched → ignore it. This shouldn’t even be a list item.

A backlog of two hundred tickets, run through this filter, usually shrinks to twenty real pieces of work.

Deliberate debt is also a tool

Debt isn’t always a mistake. Sometimes taking on debt deliberately is the right call: ship fast today, fix it once the idea is validated. This is the “fixing a wrongly drawn boundary is cheap” logic from the modular monolith piece — debt that’s cheap to fix, taken on knowingly, and recorded is healthy.

The dangerous kind is the debt that accumulates unnoticed and quietly eats the complexity budget from the boring architecture piece.


Don’t see technical debt as a source of shame; see it as a balance-sheet item. The question isn’t “do we have debt” — every system does. The question is “which one is charging interest.”

Close the debt that charges interest; live in peace with the rest.

Sources

Related

Comments

Sign in with your GitHub account to join the discussion. Comments are stored in GitHub Discussions.

Search the site

Start typing to search posts, projects and pages.

Esc to close Powered by Pagefind