How to Measure Technical Debt: A CTO's Guide to Quantifying the Invisible

Technical debt is like dark matter: you know it exists, you can infer its impact, but measuring it feels impossible. Here's how leading engineering teams actually quantify technical debt and use those numbers to make decisions.

Coderbuds Team
Coderbuds Team
Author

Technical debt is the implied cost of future rework caused by choosing an expedient solution now instead of a better approach that would take longer. It accumulates when teams prioritize speed over sustainability, and eventually demands repayment through slower development, more bugs, and frustrated engineers.

That definition sounds clean. The reality is messy.

McKinsey's research team put it bluntly: "Technical debt is like dark matter: you know it exists, you can infer its impact, but you can't see or measure it."

Except you can measure it. Not perfectly, not completely, but well enough to make decisions. Here's how.

#Why Measurement Matters

Managing technical debt is perhaps the CTO's most important responsibility. Fix too much and you ship nothing new. Fix too little and your codebase becomes unmaintainable.

The 2022 CISQ report found that technical debt and poor software quality cost the US economy $2.41 trillion annually. Your organization is paying some portion of that cost, whether you measure it or not.

Without measurement, technical debt conversations become religious debates. Engineers say the codebase is a disaster. Product says we need to ship features. Neither side has data. Nobody wins.

With measurement, you can answer concrete questions:

  • How much time does technical debt cost us each sprint?
  • Which areas of the codebase have the most debt?
  • Is our debt increasing or decreasing over time?
  • What's the ROI of investing in debt reduction?

Those questions have answers. Finding them requires the right metrics.

#The Technical Debt Ratio (TDR)

The Technical Debt Ratio expresses the relationship between the cost to fix existing debt and the cost of building the system in the first place.

Formula: TDR = (Remediation Cost / Development Cost) x 100

A team with a TDR of 10% would need to spend one hour fixing accumulated issues for every ten hours of new work. A TDR of 5% or below is generally considered healthy. Many organizations operate at 10% or higher without realizing it.

TDR provides a single number for executive conversations. "Our technical debt ratio is 12%" is easier to discuss than "the authentication module uses a deprecated library and the payment processing code has 47 code smells."

The challenge is calculating remediation cost and development cost accurately. Tools like SonarQube estimate this automatically, but the estimates are rough. The value is in trends, not absolute numbers.

#Tracking TDR Over Time

A single TDR snapshot tells you very little. TDR over time tells you whether your debt is growing or shrinking.

Plot TDR monthly. If the line trends upward, you're accumulating debt faster than you're paying it down. If it trends downward, your investment in code quality is working.

Most teams find their TDR increases during crunch periods and decreases during maintenance phases. That's normal. What you want to avoid is a steady upward trend with no recovery.

#Google's Approach: Surveys Plus Log Data

Google's engineering productivity team uses a dual strategy: quarterly developer surveys and engineering log data analysis.

The surveys capture engineers' perceptions: How much time do you spend working around technical debt? How often does debt slow you down? Which areas of the codebase cause the most friction?

But Google's researchers found a significant limitation: quarterly surveys are lagging indicators. By the time survey results reveal a debt problem, it's already been building for months.

So they developed metrics based on engineering log data to capture real-time signals. Their focus was on three forms of technical debt:

Code degradation: Code that has become harder to understand or modify over time. Measured through complexity metrics, code churn, and defect clustering.

Teams lacking expertise: Areas of the codebase where the original authors have left and current maintainers lack context. Measured through ownership concentration and knowledge distribution.

Migration needs: Dependencies on deprecated technologies, outdated APIs, or end-of-life systems. Measured through dependency scanning and manual tracking.

Google's researchers examined 117 potential metrics and used linear regression to assess which ones predicted engineers' perceptions of technical debt. The strongest predictors combined log data signals with survey responses.

#The Three Core Indicators

Research across multiple organizations points to three metrics that consistently correlate with technical debt: ownership, cohesion, and churn.

#Ownership

Who owns each part of the codebase, and how concentrated is that ownership?

Code with clear ownership gets maintained. Code with diffuse ownership becomes everybody's problem and nobody's responsibility.

Measure ownership by tracking who touches which files. If a module has contributions from 15 different developers over the past year with no clear maintainer, that's a debt risk. If one person owns 90% of the commits but left the company six months ago, that's a different debt risk.

Healthy codebases have clear ownership with reasonable bus factor. Unhealthy codebases have either nobody in charge or single points of failure.

#Cohesion

How logically organized is your codebase?

Low cohesion shows up as files that change together even though they're in different modules, classes with responsibilities that don't fit their names, and circular dependencies between components.

Cohesion is harder to measure automatically but shows up in:

  • Commit coupling: Files that always change together might belong together
  • Logical complexity: Classes or modules that do too many things
  • Dependency graphs: Circular or tangled dependencies indicate structural debt

When developers consistently need to change multiple unrelated files to implement a single feature, that's a cohesion problem signaling structural debt.

#Churn

How often does code get rewritten or significantly modified?

Code churn refers to the percentage of recently written code that gets modified or deleted shortly after. High churn suggests instability: unclear requirements, architectural problems, or debt that forces constant rework.

Normal churn exists. New features get refined. Bugs get fixed. But if the same files keep changing sprint after sprint, something is wrong.

Track churn at the file and directory level. Files with churn rates significantly above the baseline are candidates for refactoring or redesign.

#Time-Based Metrics

#Developer Time Lost to Debt

One straightforward approach: ask developers how much time they lose to technical debt.

This can be done with a simple spreadsheet during sprint retrospectives. For each sprint, have the team estimate hours lost to:

  • Working around problematic code
  • Debugging issues caused by architectural problems
  • Waiting for slow tests or builds
  • Onboarding friction from poor documentation or organization

Over two years with four teams, one study found developers reported losing an average of 7% of their time to technical debt. That's more than three hours per week per developer spent on debt-related friction.

The advantage of time-based measurement is that it's directly actionable. If you're losing 7% of engineering capacity to debt, you can calculate the dollar cost and compare it against the cost of remediation.

#Lead Time Impact

Technical debt slows delivery. If your lead time for changes increases over time, debt is often the cause.

Track lead time monthly and look for upward trends. When lead time increases despite no changes to team size or process, the codebase is probably getting harder to work in.

Compare lead time across different areas of the codebase if possible. Areas with more debt should show longer lead times for equivalent changes.

#Code Quality Metrics

#Cyclomatic Complexity

Cyclomatic complexity measures the number of independent paths through code. Higher complexity means more decision points, more branches, more ways for things to go wrong.

A function with complexity of 5 has five paths to test. A function with complexity of 50 is nearly impossible to test thoroughly and probably impossible to understand.

Complexity above 10 is a warning sign. Complexity above 20 is a refactoring target. Complexity above 50 is legacy code that nobody wants to touch.

Track average complexity over time and the count of files above your threshold. Rising complexity is debt accumulation.

#Test Coverage Gaps

Missing tests aren't just a quality problem, they're a debt problem.

Untested code is harder to change safely. Every modification risks breaking something that was working. This creates pressure to leave code alone even when it needs improvement.

Track test coverage, but focus on coverage of high-churn areas. 80% overall coverage means little if the most-frequently-changed files have 20% coverage.

#Code Duplication

Duplicated code is debt. Every duplicate means multiple places to update when requirements change, multiple places for bugs to hide, and multiple places where behavior can diverge.

Duplication metrics are easy to generate automatically and easy to understand. If you have 10% code duplication, roughly one in ten lines exists in multiple places.

Watch duplication trends especially during AI adoption. Code duplication is up 4x in some organizations using AI coding tools. The agents produce working code quickly but don't necessarily recognize when they're duplicating existing functionality.

#Building a Technical Debt Dashboard

Individual metrics are useful. A dashboard that combines them is powerful.

#Suggested Components

Technical Debt Ratio (monthly trend): The headline number for executive conversations.

Time Lost to Debt (sprint-by-sprint): Survey-based metric from retrospectives.

High-Debt Files (updated weekly): Files with high complexity, low coverage, and high churn.

Ownership Gaps (monthly review): Areas without clear maintainers.

Trend Lines (all metrics): Debt measurement is about trends more than absolute values.

#Making Debt Visible

The dashboard should be visible to both technical and non-technical stakeholders. When product managers can see that the payment module has a TDR of 25%, they understand why changes there take longer.

Some teams assign a "debt score" to each area of the codebase and display it alongside sprint planning tools. When planning work in a high-debt area, the score provides context: this will take longer because of accumulated debt.

#Setting Debt Budgets

Raw measurement isn't enough. You need a policy for how much debt is acceptable.

#The 80/20 Approach

Many teams adopt an 80/20 rule: 80% of sprint capacity goes to new features, 20% goes to debt reduction.

This prevents debt accumulation during normal work while ensuring continuous progress on new functionality.

#Debt Sprints

Other teams schedule periodic "debt sprints" focused entirely on cleanup and refactoring. One sprint in eight, one in four, whatever frequency matches your accumulation rate.

Debt sprints work well for tackling large refactoring efforts that don't fit into regular work. They work poorly if they become the only time debt gets addressed.

#Debt-Adjusted Estimates

Some teams add a "debt tax" to estimates for work in high-debt areas. If the payment module has a TDR of 15%, multiply estimates for payment work by 1.15.

This makes the cost of debt visible in planning conversations and creates incentive to reduce debt in frequently-modified areas.

#What Tools Help

#SonarQube

SonarQube is the most commonly cited tool for technical debt measurement. It provides automated analysis of code quality, security issues, and estimated remediation cost.

The remediation estimates are rough, but they're consistent. Track SonarQube's debt estimate over time to see trends.

#Code Climate

Code Climate focuses on maintainability, calculating a GPA-style grade for your codebase based on complexity, duplication, and other factors.

The letter grades are helpful for executive communication. "Our codebase is a B-" is easier to discuss than a list of metrics.

#Custom Metrics

Many teams build custom debt tracking suited to their specific challenges. If your main debt problem is test coverage, build a coverage dashboard. If it's dependency management, track dependency age and vulnerability counts.

The best tool is the one you'll actually look at.

#Making Debt Decisions

Measurement enables decisions, but doesn't make them for you.

#Prioritizing Debt Reduction

Not all debt is equal. Prioritize debt that:

  • Lives in frequently-modified code (high-churn areas)
  • Blocks feature development (dependencies, architectural constraints)
  • Creates security or compliance risk
  • Frustrates developers (affecting retention)

Debt in rarely-touched code can wait. Debt in your hot paths demands attention.

#Justifying Investment

With measurement, you can calculate ROI for debt reduction efforts.

If developers lose 7% of time to debt, and your engineering budget is $2M annually, that's $140K in lost productivity. A $50K investment in debt reduction that cuts that loss to 4% pays for itself in under a year.

These calculations are rough, but they make the business case visible.

#Knowing When to Pay Debt

Sometimes the right answer is to live with debt. If a legacy module is scheduled for replacement in six months, investing in its cleanup makes no sense.

Measure debt, but apply judgment to the numbers. Context matters.

#Common Mistakes

#Measuring Everything

Don't track 117 metrics like Google's research team. Track three to five that matter for your context. More metrics means more noise and less signal.

#Ignoring Perception

Technical metrics don't capture everything. Developer surveys fill the gaps. If engineers feel like the codebase is a nightmare but your metrics say it's fine, trust the engineers.

#Focusing on Absolute Numbers

Technical debt metrics are most useful as trends. A TDR of 8% means little in isolation. A TDR that increased from 6% to 10% over six months tells a clear story.

#Making It Punitive

Debt measurement should inform decisions, not punish people. If teams fear that high debt metrics will lead to blame, they'll game the metrics or avoid measuring at all.

#Treating All Debt Equally

Debt in your authentication system is more dangerous than debt in your admin dashboard. Weight your attention toward high-impact areas.

#Getting Started

If you're not currently measuring technical debt, start simple:

Week 1: Set up SonarQube or similar tool. Get baseline metrics for TDR and complexity.

Week 2: Add a debt question to your retrospective. Ask developers to estimate hours lost to debt each sprint.

Week 3: Identify your highest-churn files. Cross-reference with complexity metrics. These are your debt hotspots.

Week 4: Build a simple dashboard showing TDR, time lost, and hotspots. Review monthly.

You don't need perfect measurement to start making better decisions. You need good-enough measurement that improves over time.

#Related Reading


Technical debt affects your DORA metrics, your team health, and your ability to ship. Coderbuds tracks change failure rate, cycle time, and code review patterns that signal debt accumulation. Start measuring what matters.

Coderbuds Team
Written by

Coderbuds Team

The Coderbuds team writes about DORA metrics, engineering velocity, and software delivery performance to help development teams improve their processes.

View all posts

You're subscribed!

Check your email for a confirmation link. You'll start receiving weekly engineering insights soon.

Want more insights like this?

Join 500+ engineering leaders getting weekly insights on DORA metrics, AI coding tools, and team performance.

We respect your privacy. Unsubscribe anytime.