Blueprint mode is on — see the design decisions behind this site

Technical debt: when to take it on and when not to

Technical debt isn't always bad. Like a loan, taken deliberately and with a repayment plan it can help a product move faster. How to tell good debt from bad, and how to pay it down without stopping delivery.

Technical debt is a term everyone uses and each person defines differently. For some, any code they dislike is technical debt. For others it is an excuse to rewrite everything.

A sharper definition: a future cost you accepted today in order to move faster.

The loan analogy

Technical debt works like a loan. A loan isn't bad in itself. If it buys something that creates value and you can make the payments, it was a good decision. It goes wrong in three ways:

  • You don't know you borrowed.
  • You have no plan to repay.
  • The interest grows until it eats everything you earn.

In software, the interest is the gradual slowdown of every new change.

Two kinds of debt

Deliberate debt. You chose a simpler build to reach the market sooner, you know what you gave up, and you recorded it. For example: "reports are generated nightly for now, not live. If usage grows, we change that."

Accidental debt. It comes from carelessness, haste or missing design. Nobody decided anything; it just happened. This kind is dangerous because it stays invisible until it is expensive.

When taking on debt makes sense

  • You don't yet know whether the product works. Spending weeks perfecting something that may be discarded is waste in its own right.
  • The shortcut sits behind a proper boundary. If the simplified part can be replaced later without touching the rest, the debt is cheap.
  • The deadline is real. Not imagined — an event or commitment that truly cannot move.

When not to borrow

Some debts carry very high interest and are almost never worth it:

  • Security and user data. "We'll secure it later" means an incident is on its way. See security from day one.
  • The core data model. Fixing data structures once real data has accumulated is painful and risky.
  • System boundaries. Once modules tangle, separating them is a rewrite.
  • No tests at all on critical logic. Without tests every later change is a gamble.

Write the debt down

Debt that isn't recorded becomes accidental debt. For each deliberate debt, record three things:

  1. What was simplified?
  2. What signal says it is time to fix it? For instance, "when concurrent users pass a given level."
  3. Roughly how much work is the fix?

The natural home for this is an architecture decision record.

Paying it down without stopping

A common mistake is asking for "two months to clear debt". That request is rarely granted, and when it is, the product stands still for two months.

A better approach:

  • Fix along the way. Each time you work in an area, leave it a little cleaner.
  • Reserve a fixed share. A set portion of each cycle goes to repayment.
  • Pay the highest interest first. The part that changes most and slows you most comes first. Ugly code nobody touches can wait.

Signs the debt is out of control

  • Estimates for simple work keep rising.
  • Every change breaks something unrelated.
  • People are afraid to touch parts of the code.
  • New hires take months to become useful.

If you see these, debt has stopped being a technical topic. It is a business risk.

The takeaway

The goal isn't zero debt; it is known debt. Debt taken on deliberately, written down, with a clear trigger for repayment, is a tool for speed. Everything else is a cost growing quietly.

Related: swappable layers.

Written by

Mohammad Ali Eslamipour

Mohammad Ali Eslamipour is a digital product architect who defines, architects and — with his own engineering team — ships AI products, SaaS platforms and web apps.