Engineering

Technical Debt: How to Put a Number on It Before Your Next Sprint

May 2026 · 9 min read

Verdict up front: Stop arguing about tech debt with vibes. Measure it (SonarQube technical debt ratio is one good metric: total remediation effort / total development effort). Prioritise by interest rate: high-change-frequency code with high debt = highest interest = fix first. Aim for under 10% TD ratio and 20% of engineering time allocated to debt reduction.

The interest rate analogy

Tech debt works like financial debt. When you take shortcuts to ship faster, you accumulate principal. The "interest" you pay is the extra time every future change in that code takes.

Some debt has high interest (charged frequently): a messy auth system you touch every sprint costs you 30% extra time on every feature. Some debt has low interest: a clunky internal reporting script you touch twice a year barely costs you anything.

Refactoring is "paying off the principal." The question isn't "should I refactor?" — it's "which debt has the highest interest rate?"

Measuring tech debt: the SonarQube approach

SonarQube calculates technical debt ratio as:

TD ratio = (remediation cost in hours) / (development cost in hours) × 100%

Where:

  • Remediation cost: SonarQube estimates the effort to fix all detected code smells based on rule severity
  • Development cost: Estimated using lines of code × cost per line (default 0.06 hours/LOC)

Industry benchmarks:

  • Under 5%: Excellent (uncommon)
  • 5-10%: Healthy
  • 10-20%: Concerning, plan refactoring
  • 20-40%: Paying significant interest on every change
  • Over 40%: Consider rewrite or modular extraction

Real numbers from teams we've audited: most teams discover 15-30% TD ratio when first measured. The shock is healthy — it makes "we have some tech debt" concrete.

Free metrics you can compute today

No need for SonarQube to start. Useful proxies:

Code volatility

Files modified most often in the last 90 days. These are high-interest if they're also messy.

git log --since="90 days ago" --name-only --pretty=format: \
  | sort | uniq -c | sort -rn | head -20

Cross-reference with code complexity. A file in the top 20 by volatility AND top 20 by complexity = highest priority.

Test coverage gap

Files without corresponding test files = highest risk per change.

# Python example
find . -name "*.py" -not -path "*/test*" \
  | xargs -I{} sh -c 'test -f "tests/test_$(basename {})" || echo "{}"'

Longest functions

Functions over 50 lines are debt magnets. Find them:

# Python
pip install --user radon
radon cc -nc -s -a .

Anything with cyclomatic complexity over 15 is a refactor candidate.

Dependency age

# Node
npm outdated --long

# Python
pip list --outdated

Packages more than 2 major versions behind = security and compatibility debt.

Build time

If your CI takes 30+ minutes, you're paying interest every PR. Track build time over time — if it's growing, debt is accumulating.

The prioritisation matrix

Score each piece of debt on three axes:

Axis1 (low)5 (high)
Effort to fix1-2 days1-2 months
Change frequency (how often this code is modified)Rarely (once/quarter)Often (multiple times/week)
Risk if untouched (bugs, security, performance)CosmeticProduction incidents

Priority = (Change frequency × Risk) / Effort

Highest scores: high-change + high-risk + low-effort. Fix these first.

Lowest scores: rarely-touched + low-risk + high-effort. Leave alone, possibly forever.

Side-by-side: debt types

Debt typeInterest rateFix priority
Slow CI/CD pipeline (30+ min builds)Very highTop priority
No tests on critical auth/payment codeVery highTop priority
Outdated dependencies with CVEsVery high (security)Top priority
Monolithic file in active developmentHighSchedule refactor
Inconsistent code styleMediumAuto-fix with linter
Outdated dependencies, no CVEsLowUpdate during minor work
Old comments, dead code in cold pathsVery lowDefer indefinitely
Old framework version (still supported)LowPlan for major refactor cycle
Stale documentationMedium (onboarding cost)Update as you touch code

The 20% rule

Industry consensus: allocate 20% of engineering time to debt reduction. Practical implementations:

  • Friday afternoon refactor: Each developer spends Friday afternoon on tech debt of their choosing.
  • Tech debt sprint: Every 4th sprint is dedicated to debt. Strong commitment, easier to defend to product.
  • Boy scout rule: Leave code cleaner than you found it. Each PR fixes one small issue. Compounds over time.
  • Debt budget per feature: Each feature PR has 20% headroom for adjacent cleanup. Embedded in normal work.

The boy scout rule sounds gentle but is the most effective. A team of 5 developers fixing 1 small thing per PR = 50+ small fixes per month. Compounded over a year, that's transformative.

When to declare bankruptcy

Sometimes refactoring is more expensive than rewriting. Signs you should consider a rewrite over incremental refactor:

  • TD ratio over 40% on a core system
  • Every feature takes 3-5x longer than estimated
  • New hires take 6+ months to be productive
  • Core dependencies are EOL (Python 2, Node 12, Rails 4)
  • You can't deploy to production without manual steps
  • Your build/test cycle is 2+ hours

Even then, prefer strangler-fig over rewrite-from-scratch. Build the new system alongside the old, route traffic gradually, retire old code in chunks.

Cost of NOT measuring

Unmeasured tech debt:

  • Estimates miss by 2-3x consistently (you're paying interest you can't see)
  • Engineers burn out fixing the same fires repeatedly
  • New hires struggle to onboard (the "tribal knowledge" tax)
  • Product team thinks engineering is slow (engineering can't articulate why)

Measured tech debt:

  • You can show product "this feature is 50% slower because of debt in module X"
  • You can prioritise refactor work against feature work with data
  • You can track whether you're getting better or worse over time
  • You can justify the 20% allocation to skeptical stakeholders

Tools worth using

  • SonarQube / SonarCloud: Free for open source, €11/month/user for private. TD ratio + code smells.
  • CodeClimate: Similar to SonarQube, simpler UI, $20/seat/month.
  • Code Scene: Behavioural analysis (which files are hotspots based on commit history). Open source + paid SaaS.
  • Snyk: Dependency vulnerability tracking. Free tier covers most needs.
  • Dependabot: Free, automatic dependency updates. GitHub-native.

Tech debt blocking your roadmap?

We audit codebases, quantify tech debt in hours, and produce a prioritised refactoring plan. Typical 50k-line codebase audit: 1 week, €4-6k.

Book a discovery call

Related Posts

iOS App Development TimelineCustom CRM Development CostMobile App Maintenance Cost
← All blog posts

Need a tech debt action plan?

Free 20-min call: we look at your repo metrics, deployment friction, and bug rate to estimate your real tech debt burden and what to do first.

Book a discovery call