Engineering LeadershipMarch 16, 2026 · 12 min read

How to Measure Technical Debt (Without Lying to Yourself)

Every engineering organization has technical debt. Most cannot quantify it. The teams that can quantify it get budget to address it — because they can show executives a dollar figure and a compound interest curve, not just a vague engineering concern. Here is how to build a credible debt measurement system from the data you already have.

What this guide covers

The measurement problem with invisible debt, proxy metrics that correlate with accumulation, direct measurements from static analysis, how to calculate debt cost in dollars, a prioritization matrix for high-risk files, and a communication framework that lands with executives — including the compound interest model.

The Measurement Problem: Technical Debt Is Invisible Until It Is Not

Ward Cunningham introduced the debt metaphor in 1992 to explain to non-technical stakeholders why rushed code creates future costs. The metaphor was brilliant and also accidentally harmful: it implied that debt could be clearly defined and tracked like a balance sheet. In practice, technical debt is distributed, heterogeneous, and contextual. A 10-year-old class with no tests might be the highest-debt item in one codebase and completely inconsequential in another, depending on whether it is ever called.

The invisibility of debt is its primary danger. Delivery slows down, bugs increase, onboarding takes longer, and no one can point to why. The engineers know, but they struggle to translate "we have a lot of debt in the payments module" into something an executive can act on. The result: debt accumulates, delivery degrades, and the first sign for leadership is when engineers start leaving or a major feature takes three times as long as estimated.

The goal of debt measurement is not a perfect balance sheet — it does not exist. The goal is early warning signals, a prioritized list of where debt is actively slowing you down, and a dollar figure that gives executives a reason to allocate time to fix it.

Proxy Metrics: What Correlates With Debt Accumulation

The most useful debt signals come from behavioral patterns in your development data — how engineers interact with the code over time. Code that is heavily indebted tends to produce characteristic patterns: it is modified frequently but never durably, it generates more review comments than healthy code, and it takes longer per line of change to ship safely.

Code Churn Rate

Lines of code modified repeatedly within a short window (30–90 days). High churn on the same files signals code that is not truly fixed when changed — each change creates follow-on problems.

Files with >3 revisions per month for 3+ months = high debt candidate

PR Cycle Time Growth

If cycle time is increasing on a specific repository or module over time — even while the team is the same size — that module is getting harder to change. Debt is accumulating.

Module cycle time growing >20% quarter-over-quarter without team size change

Bug-to-Feature Ratio

The ratio of bug fix tickets to feature tickets over a rolling 30 days. As debt accumulates, more engineering time shifts from building to fixing. A rising bug ratio is a debt early warning.

>40% of closed tickets are bug fixes = elevated debt signal

Test Coverage Decline

Falling coverage on active modules (not legacy dead code) signals that new code is being written without tests — debt is being actively added. Coverage should hold steady or improve in healthy codebases.

>5% coverage decline in an active module over 90 days

Reviewer Comments Per PR (Trend)

Rising review comment density in a module over time suggests code that is getting harder to understand and harder to review correctly. Reviewers leave more questions when the code is confusing.

Comments per PR growing >30% quarter-over-quarter in a module

Rework Rate

The percentage of PRs that fix bugs introduced by code merged in the last 30 days. High rework rates signal that recent changes are fragile — insufficient tests, unclear interfaces, or rushed implementation.

>15% of bug fix PRs reference commits from the last 30 days

Direct Measurements: What Static Analysis Tells You

Proxy metrics from development behavior are leading indicators — they tell you debt is accumulating before it becomes a crisis. Static analysis tools give you direct measurements of the debt that already exists in the codebase.

SonarQube technical debt score

SonarQube calculates a technical debt score in hours — the estimated remediation time for all identified code smells, using SQALE methodology. This is not a perfect measure (it treats all code smells equally regardless of whether the code is ever executed) but it is a useful baseline. Track the absolute number and the trend. If the debt score is growing faster than the codebase is growing, debt is accumulating faster than it is being paid down.

SonarQube also calculates a debt ratio (technical debt as a percentage of the cost to write the code from scratch). A debt ratio above 5% is considered a maintenance concern; above 10% is a reliability risk.

Code smell count and categories

Not all code smells are equal. Track smells by severity (blocker, critical, major, minor) and by category. Blocker and critical smells in active, high-traffic code are the highest priority. Minor smells in legacy code that is never changed can safely be deprioritized. The combination of severity and churn rate is the right triage lens.

Duplicated lines percentage

Duplicated code is the most expensive form of technical debt because every bug fix and requirement change must be applied in multiple places. SonarQube, CodeClimate, and similar tools calculate duplicated lines as a percentage of the codebase. Above 15% duplication is a significant maintenance burden; above 25% typically means major abstractions are missing.

Duplication percentage is also one of the easier metrics to trend over time — it is resistant to gaming, consistently measured, and directly correlated with the maintenance cost of changes.

Rework rate (30-day lookback)

Rework rate — the percentage of PRs that are fixing defects introduced by code merged in the last 30 days — is one of the most powerful direct debt signals. It measures whether recent changes are introducing new problems rather than just improving existing ones. High rework rates indicate that code quality is insufficient to sustain stable delivery: the team is running to stand still.

MeasurementToolHealthyConcern
Debt ratioSonarQube< 5%> 10%
Duplicated linesSonarQube / CodeClimate< 5%> 15%
Test coverage (active modules)Codecov / SonarQube> 80%< 60%
Rework rate (30d)GitHub / engineering metrics< 5%> 15%
Blocker / critical smellsSonarQube0 in prod code> 5 in active paths

How to Calculate the Cost of Technical Debt in Dollars

The calculation that gets executive attention is a dollar figure. Here is a simple model that is defensible without being a false precision exercise:

Debt Cost Calculation Model

1

Baseline overhead per PR

Measure cycle time for PRs in high-debt modules vs. low-debt modules. The delta is the per-PR overhead attributable to debt.

High-debt module: 4.2 day cycle time. Low-debt baseline: 1.8 days. Delta: 2.4 days per PR.

2

Weekly PR volume in affected modules

Count the PRs touching high-churn, high-debt files per week across the team.

18 PRs per week touch high-debt modules.

3

Weekly engineer-hours lost to debt overhead

Delta (in hours) × weekly PR volume

2.4 days × 8h/day × 18 PRs = 345 engineer-hours per week

4

Annual cost at loaded engineering rate

Weekly hours × 52 weeks × loaded hourly rate

345h × 52 × $150/hr = $2.7M annual drag from debt in these modules

Important caveat: This model measures the cost of debt that is actively slowing you down, not all technical debt in the codebase. Debt in dead code, legacy systems that are never touched, or future-state concerns is real but a lower priority than debt that is impeding delivery today.

Prioritization Matrix: Where to Attack Debt First

Not all debt is equally urgent. The files most worth prioritizing are those where debt is actively slowing you down — high-churn files with low coverage. The prioritization matrix plots two dimensions:

  • Churn rate: How often is this file modified? High-churn files are touched frequently — debt in them compounds faster and is felt more acutely.
  • Coverage: What percentage of the file is covered by tests? Low coverage means changes are made without safety nets — higher probability of regressions.

The highest-priority debt targets are in the top-left quadrant: high churn and low coverage. These files are changed often, and each change is made without the protection of a test suite. They produce the most bugs, the most rework, and the longest cycle times. Starting here gives you the fastest ROI on debt reduction investment.

Priority 1

High Churn + Low Coverage

Changed frequently, no safety net. Every change risks a regression. Fix tests here first, then refactor.

Priority 2

High Churn + High Coverage

Actively changing with test coverage. Debt here is manageable — prioritize refactoring when cycle time starts growing.

Priority 3

Low Churn + Low Coverage

Rarely touched, no tests. Debt is latent. Prioritize when a feature requires changes to this module; add tests before modifying.

Monitor Only

Low Churn + High Coverage

Stable, well-tested. Debt here is unlikely to cause delivery problems. Track but do not prioritize over higher-risk quadrants.

Communicating Technical Debt to Executives

The most effective framing for executive communication is the compound interest model. Research published in the IEEE Software journal and echoed across industry practitioners consistently finds that ignored technical debt doubles its drag on velocity every 12–18 months. The mechanism is compounding: debt makes code harder to understand, which slows new development, which causes developers to take shortcuts to meet deadlines, which creates more debt.

The compound interest analogy lands with business stakeholders because they understand it intuitively: "If we do not address this now, the cost doubles in 18 months. The $2.7M annual drag we are experiencing today becomes a $5.4M drag by the end of next year if the trend continues." This is not speculation — it is a model based on your actual cycle time trends and rework rates.

The debt conversation framework

Structure the executive conversation around three numbers:

  • Current cost: The annual engineer-hours lost to debt overhead, converted to dollars at loaded rate. Use the calculation model above.
  • Trend: Is the cost growing or stable? Show cycle time trends in the high-debt modules over the last two to four quarters. A growing trend with the compound interest projection is the most compelling data point.
  • Investment required: How many engineer-weeks of focused debt reduction would eliminate the Priority 1 items? What is the payback period? If 4 weeks of investment reduces annual drag by $500K, the payback period is weeks, not years.

Building a Debt Health Score

A single composite score makes debt easy to track over time and easy to communicate. Here is a simple debt health score that combines the key signals:

Debt Health Score Components

30%

Coverage Score

Average test coverage across active modules. Normalize to 0–100: 80%+ coverage → 100 score, 60% → 60, below 40% → 0.

30%

Churn-to-Fix Ratio

Files modified 3+ times per month that have also received bug fixes. Higher ratio = lower score. Normalize to 0–100.

20%

Cycle Time Trend

Quarter-over-quarter change in median cycle time for the highest-churn modules. Improving = higher score; degrading = lower score.

20%

Rework Rate

Percentage of PRs that are bug fixes for code merged in the last 30 days. Below 5% → 100 score, above 15% → 0 score.

Composite score: Weighted average of the four components → single 0–100 score. Target: above 70. Below 50 requires a dedicated debt reduction sprint. Track weekly and report monthly to engineering leadership.

Making Debt Reduction Sustainable

The worst pattern in technical debt management is the "debt reduction sprint" that fires and is then forgotten. Debt accumulates continuously; point-in-time remediation is a losing strategy unless you also change the flow that creates debt.

The most sustainable approach is a debt budget: a standing allocation of 15–20% of engineering capacity per sprint for debt reduction, applied to the highest-priority items in the prioritization matrix. Combined with a norm that every change to a high-debt file includes at least one test for previously uncovered behavior, this creates a flywheel where the code improves incrementally with every delivery cycle.

Track the debt health score monthly. When the score drops below a threshold (50 is a reasonable trigger), convene a focused remediation effort. When it is above 70, maintain the 15–20% budget as insurance. The goal is not zero debt — that is both impossible and unnecessary. The goal is debt at a level that does not meaningfully impede delivery.

Surface your debt signals automatically

Koalr tracks code churn rate, PR cycle time trends, rework rate, and coverage trends across your repositories — automatically, without manual data collection. Identify your highest-priority debt hotspots in minutes and build an executive-ready cost model from your actual delivery data. Ask the AI chat "which modules have the most technical debt based on churn and cycle time?" and get a ranked, data-backed answer.