Blog

Most Technical Debt Is a Leadership Decision, Not an Engineering Accident

Technical debt rarely starts in code. It starts in planning: incentives, deadlines, and trade-offs made without naming the long-term cost.


Share this article

Technical debt is not a mysterious engineering failure. It is a predictable outcome of how leadership budgets time, risk, and attention.

Technical debt is usually explained as an engineering problem.

Messy code. Bad abstractions. Weak discipline. A team that moved too fast and paid the price.

That story is convenient because it points downward. It makes the cause feel local, technical, fixable by better engineers and stricter reviews.

It is also often wrong.

This essay sits underneath many of the problems teams argue about separately:
slow delivery, fragile systems, constant rewrites, process bloat, and burned-out engineers. They are often the same issue expressed in different forms, including premature architectural complexity and quiet process drift.


The term meant something precise before it became a blame tool

Ward Cunningham coined the term technical debt in 1992 to describe a deliberate shortcut taken to ship sooner, with the explicit understanding that the design would be improved later.

The metaphor was intentional. Like financial debt, it only works if two things are acknowledged:

  • you are borrowing time today
  • repayment is planned, owned, and real

In many organizations, the metaphor gets inverted:

Manager: "Why is this taking so long? You said two weeks."
Engineer: "We can ship, but the core is tangled. We will pay interest."
Manager: "So you're saying the old team did a bad job?"
Engineer: "No. I'm saying we made trade-offs and never repaid them."
Manager: "Ok. Can we still get it out this sprint?"

And just like that, debt becomes a character flaw. The metaphor stops being a tool for clarity and becomes a tool for blame.


Technical debt is not bad code, it is an unpaid bill

Bad code is just bad code. It can be cleaned up, refactored, rewritten.

Technical debt is different. It is what happens when you buy short-term speed with long-term complexity and do not budget the repayment.

A useful definition:

Technical debt is the recurring cost of decisions that make the system harder to change, taken to hit a near-term goal, without a plan to restore changeability.

Debt is not the shortcut. Debt is the shortcut plus the absence of repayment.

The moment you say "we will fix it later" without naming who, when, and what "fixed" means, you have created debt.


The part most teams miss: debt is a risk transfer

The deepest thing about technical debt is not code quality.

It is risk transfer.

Leadership gets the upside now:

  • a launch date met
  • a client saved
  • a demo that lands
  • a roadmap item checked off
  • a milestone supported

The downside is pushed into the future and transferred to:

  • engineers (firefighting, on-call pain, brittle releases)
  • product (slower iteration, higher cost per feature)
  • customers (bugs, latency, inconsistent behavior)
  • the business (missed opportunities because change becomes hard)

Debt is an organizational way of borrowing from the future.

Borrowing can be smart. Some deadlines are real. Some windows close. Some bets are worth it.

The failure mode is not borrowing. It is borrowing while denying you borrowed, and repeating that denial until it becomes structural.


Where debt is actually created

Most debt is not born in pull requests.

It is born in meetings where the organization decides what it will reward and what it will punish.

Common leadership choices that manufacture debt:

  • setting deadlines as commitments, not targets
  • measuring feature count instead of flow (lead time, predictability, reliability)
  • treating cleanup as optional while delivery is mandatory
  • funding new work while leaving maintenance unfunded
  • incentivizing visible progress over reduced fragility
  • asking for speed while denying the capacity that speed consumes

Engineers respond to the gradient you create.

When the system tells them "ship is safety," they ship.
When the system tells them "slowing down is failure," they avoid slowing down.
When the system tells them "refactors do not count," refactors do not happen.

This is not an engineering defect. It is a rational response to incentives.

PM: "We promised this by end of month."
Engineer: "We can hit the date if we skip tests and hardcode the workflow."
PM: "How risky is that?"
Engineer: "Not risky for the demo. Risky for everything after the demo."
PM: "We’ll clean it up next sprint."
Engineer: "Whose sprint are we borrowing from?"


Engineers are not innocent either, but incentives decide the ceiling

Engineers can create debt locally:

  • over-engineering "just in case"
  • novelty chasing (new framework, new architecture, new shiny)
  • clever abstractions that nobody can maintain
  • skipping tests and observability because it is boring
  • tolerating broken review culture

But there is a distinction:

Local engineering debt is usually correctable by a strong team.

Systemic debt is protected by incentives.

If the organization rewards speed and punishes care, it will generate debt even with excellent engineers. It will also regenerate debt after every refactor and every rewrite.


A practical taxonomy: not all debt is the same

The word "debt" gets abused because it lumps everything together.

In practice, teams accumulate different kinds of debt, and they carry different interest rates:

  • Architecture debt: coupling, unclear boundaries, "touch everything to change anything"
  • Quality debt: missing tests, flaky tests, slow feedback loops
  • Data debt: migrations avoided, unclear ownership, inconsistent sources of truth
  • Platform debt: build pipelines, dev tooling, CI time, environments nobody trusts
  • Operational debt: alert fatigue, manual deploy steps, incident-driven roadmap resets
  • Product debt: UX inconsistencies, edge cases ignored, support burden growing quietly

If you cannot name the category, you cannot manage the repayment.


Interest rate is the only thing that matters

Principal is what it would take to fix the debt.

Interest rate is what the debt costs you on every future change.

High-interest debt has obvious symptoms:

  • small changes require large rewrites
  • releases feel dangerous
  • bugs appear in unrelated areas
  • onboarding takes weeks
  • incident work eats planned work
  • teams avoid touching core flows
  • roadmaps become negotiations with the codebase

Debt is invisible while it is being created.

The sprint still ends. The feature still ships. The dashboard still looks green.

Then, months later, the interest shows up everywhere.


The hidden trap inside "business priorities"

"Business priorities" is often used as a conversation stopper.

It sounds objective and inevitable.

But "business priorities" is a label for a choice:

  • speed over resilience
  • scope over coherence
  • visibility over sustainability
  • short-term certainty over long-term option value

Those are not laws of nature. They are bets.

The only question is whether the bet is made consciously and managed responsibly, or made casually and denied later.

Debt does not care why it was created. It only cares that it exists, and it will charge interest either way.


Why "just refactor" rarely works

When teams finally feel pain, they often attempt to fix it with engineering heroics:

  • a big refactor initiative
  • a rewrite
  • a new architecture
  • a new framework

Sometimes it helps. Often it fails.

Why?

Because debt is not only a technical state. It is a governance failure.

If the incentive system that created debt stays the same, the organization will reproduce debt in the new codebase.

Exec: "Why don't we just rewrite it? Fresh start."
Engineer: "Rewrite doesn't remove pressure. It removes context."
Exec: "But the new system will be clean."
Engineer: "For about three weeks."
Exec: "Why?"
Engineer: "Because we kept the same incentives. Speed is still rewarded. Maintenance is still invisible."

You can move to a cleaner architecture and still end up with the same paralysis if:

  • deadlines are still non-negotiable
  • quality work is still punished by time pressure
  • teams are still measured by feature output
  • nobody is accountable for system health

The debt does not live in the code. It lives in the decision process.


The operator manual: how teams avoid crippling debt

Teams that avoid debt do not have magically better engineers.

They have management mechanics that make debt visible and repayable.

1) Name debt at the moment you take it on

Not vaguely. Specifically:

  • what is the shortcut?
  • what is the consequence?
  • what breaks if we do not repay?
  • what is the estimated principal?
  • what is the likely interest rate?

If you cannot describe it, you are not making a trade-off. You are gambling.

2) Put debt on the roadmap like real work

Not as "when we have time."

Allocate capacity explicitly. The right number depends on the system and maturity, but the key is that it is planned, not begged for.

If repayment only happens in spare time, it will not happen.

3) Assign ownership of system health

Someone must be accountable for changeability as a first-class outcome.

If ownership is diffused, debt becomes invisible.
If ownership is clear, debt becomes discussable.

4) Treat maintainability as part of delivery

Definition of done is not "it works."

It is "it works and we can safely change it next month."

This is the shift from shipping features to shipping systems.

5) Measure what debt actually damages

Most teams measure activity.

Better signals:

  • lead time to change
  • deployment frequency without chaos
  • mean time to restore service
  • change failure rate
  • defect escape rate
  • onboarding time
  • percentage of time spent in unplanned work

These metrics surface debt without turning it into a blame game.


The simplest leadership litmus test

Ask this:

When we chose this plan, did we knowingly make the system harder to change later?

If yes, then the debt is not an engineering surprise.
It is a leadership decision coming due.

The only remaining questions are:

  • did we price the interest correctly?
  • did we reserve budget to repay it?
  • do we have an owner responsible for ensuring repayment happens?

If those answers are no, then the organization is not moving fast.

It is borrowing blindly.


Closing thought

Technical debt is often discussed like weather: unfortunate, unavoidable, nobody's fault.

It is not.

It is compound interest on repeated choices about speed, scope, and responsibility.

Engineers pay it in stress.
Products pay it in fragility.
Organizations pay it in lost momentum and missed opportunities.

Debt is not shameful. Denying it is.

Technical debt is not what engineers leave behind.
It is what leadership allows to remain unpaid.

Share this article

Let’s Plan Your Next Project

If you’re building something fast, modern, and beautifully crafted — let’s talk. I help founders and teams turn ideas into polished, high-performance products.