Technical Debt Is Not Always Bad. Unmanaged Technical Debt Is.

by Eric Hanson, Backend Developer at Clean Systems Consulting

The Metaphor Worth Taking Seriously

Ward Cunningham coined the technical debt metaphor in 1992, and it's one of the more honest framings in software engineering. The key insight of the original metaphor is often lost: debt is not bad by definition. Businesses take on financial debt intentionally because the return on the borrowed capital exceeds the cost of carrying the debt. That's rational.

Technical debt is the same: you make a design decision that is expedient now but will require rework later. If the rework cost is lower than the benefit of shipping faster, taking on the debt was the right call. The mistake is not taking on debt — it's not tracking it, letting it compound invisibly, and losing the ability to make deliberate repayment decisions.

The Kinds of Debt Worth Distinguishing

Not all technical debt has the same cause or the same treatment:

Deliberate, prudent debt: "We know the right way to do this, but doing it the right way would take two weeks and we need to ship in four days. We'll take the shortcut and fix it next sprint." This is the textbook case. The debt was conscious, the tradeoff was considered, and there's an intent to repay.

Inadvertent debt: "We didn't know there was a better approach when we built this." Not negligence — just the result of learning. You know more now than you did. The design reflects what you understood then.

Reckless debt: "We don't have time to do this right." Said under pressure, without a plan to fix it, repeated across a codebase until the interest payments consume all available velocity. This is the failure mode.

The distinction matters because the remediation is different. Deliberate debt has a repayment plan. Inadvertent debt needs to be identified and evaluated. Reckless debt needs to stop accumulating before it can be paid down.

The Interest Payment Problem

Technical debt has interest in the form of slower delivery. A system with high debt levels takes longer to change because every change requires working around or through the accumulated shortcuts. New features require understanding a convoluted codebase. Bugs are harder to isolate. The time cost of debt is ongoing and compound.

The problem with compound interest on technical debt is that it's invisible on individual PRs. Each individual change is "just slightly harder" than it would be in a clean system. The aggregate effect — that your team is delivering at 60% of potential velocity because of accumulated debt — is rarely measured and almost never attributed correctly. Teams experiencing this often blame other things: unclear requirements, team churn, testing overhead.

The first step to managing debt is making its cost visible.

Making Debt Visible and Deliberate

A technical debt register is a simple mechanism: a tracked list of known debt items with rough cost estimates. Not a JIRA sprint board — a lightweight document where known shortcuts are named, their locations are specified, and their estimated impact on velocity is noted.

## Technical Debt Register

### High Priority
- **OrderService synchronous validation**: Validates payment instrument 
  synchronously in request thread. Blocks under payment provider latency.
  Estimated fix: 3 days. Impact: P99 latency spikes under load.

### Medium Priority  
- **N+1 in product recommendations**: Loads recommendation metadata 
  per-product in a loop. Acceptable at current volume, will hit database 
  hard at 5x current scale.
  Estimated fix: 1 day. Impact: minor now, significant at scale.

### Known But Low Priority
- **Legacy config format**: Config loaded from .properties and YAML mixed.
  Confusing for new engineers. No correctness impact.
  Estimated fix: 2 days. Impact: onboarding friction only.

This doesn't need to be exhaustive. It needs to capture the items that are actually affecting velocity so that when planning capacity, debt repayment can be deliberate.

The Repayment Strategy

Debt repayment rarely succeeds as a dedicated "cleanup sprint" — these get cancelled when priorities shift. The more durable approach is continuous, small repayments:

  • The boy scout rule: leave every file you touch slightly cleaner than you found it. Fix one thing that's been bothering you every time you open a file for another reason.
  • Time-boxed debt budgets: 15-20% of each sprint allocated to debt work, not negotiable downward. This keeps the interest from compounding indefinitely.
  • Pay before you extend: before building new functionality on top of a known debt area, evaluate whether the debt makes the new work significantly riskier or harder. If yes, debt repayment is a prerequisite, not optional.

The Practical Takeaway

Create a technical debt register for your current codebase — not a comprehensive audit, just the items your team talks about most. Estimate the velocity cost of each one. Bring it to the next planning session and allocate 15% of capacity to addressing the highest-cost item. Do that every sprint, consistently, and watch delivery speed increase over time as the interest payments get smaller.

Scale Your Backend - Need an Experienced Backend Developer?

We provide backend engineers who join your team as contractors to help build, improve, and scale your backend systems.

We focus on clean backend design, clear documentation, and systems that remain reliable as products grow. Our goal is to strengthen your team and deliver backend systems that are easy to operate and maintain.

We work from our own development environments and support teams across US, EU, and APAC timezones. Our workflow emphasizes documentation and asynchronous collaboration to keep development efficient and focused.

  • Production Backend Experience. Experience building and maintaining backend systems, APIs, and databases used in production.
  • Scalable Architecture. Design backend systems that stay reliable as your product and traffic grow.
  • Contractor Friendly. Flexible engagement for short projects, long-term support, or extra help during releases.
  • Focus on Backend Reliability. Improve API performance, database stability, and overall backend reliability.
  • Documentation-Driven Development. Development guided by clear documentation so teams stay aligned and work efficiently.
  • Domain-Driven Design. Design backend systems around real business processes and product needs.

Tell us about your project

Our offices

  • Copenhagen
    1 Carlsberg Gate
    1260, København, Denmark
  • Magelang
    12 Jalan Bligo
    56485, Magelang, Indonesia

More articles

How Bureaucracy Slows Down Deployment

Ever felt like your code is ready to ship, but approvals and forms keep piling up? Bureaucracy might be protecting processes—but it’s also throttling productivity.

Read more

The Real Cost of a Senior Backend Hire in Copenhagen — And What Smart Founders Do Instead

You thought a senior backend hire would cost DKK 70K a month. The real number — once Denmark's employer obligations are factored in — is closer to DKK 100K. And that's before the recruiter calls.

Read more

Second-Level Cache in Hibernate — When It Helps and When It's a Trap

Hibernate's second-level cache sits between the application and the database, caching entities across sessions. Configured correctly it eliminates repeated reads. Configured wrong it serves stale data silently, produces hard-to-debug invalidation failures, and breaks distributed deployments.

Read more

Why New York Fintech Startups Are Quietly Outsourcing Backend Work to Async Contractors

Your compliance team is growing faster than your engineering team. And somehow you're still behind on the payments integration that was supposed to ship last quarter.

Read more