How to Decide Which Technical Debt to Pay Down First
Every codebase has a list of things everyone agrees are bad. The hard part isn't identifying technical debt, it's deciding which items on that list are actually worth fixing this quarter, and which ones can keep sitting there without real cost.
How do you score technical debt beyond how bad it looks?
A genuinely ugly piece of code that nobody has touched in a year costs you almost nothing right now. A moderately messy module that every feature this quarter has to touch is actively slowing the whole team down every single week.
Weight your debt list by how often engineers actually work in that area, not just by how bad it looks. The worst code in your system, if it's untouched, is a lower priority than mediocre code sitting directly in your team's daily path.
Watch Deploy Frequency as an Early Warning Signal
A team's deployment frequency tends to drop quietly as debt accumulates in the areas people touch most, because every change in a tangled area takes longer to test and ship safely1. If your deploy cadence has been slowing down over the last few months without an obvious external cause, that's worth investigating as a debt signal before it's treated as just a busy quarter.
This is a more honest metric than a subjective "the code feels bad" complaint, because it's something you can actually track over time and point to when arguing for remediation time.
Separate Debt That Slows You Down From Debt That's Just Ugly
Some technical debt is purely aesthetic, inconsistent naming, an outdated pattern that still works fine. Other debt is structural, tight coupling that makes every change risky, a missing test suite that makes refactoring dangerous. The structural kind deserves priority even when it's less visually offensive, because it's the kind that compounds.
When you're building your priority list, tag each item honestly: is this slowing anything down, or does it just bother the engineer who has to look at it? Both are valid to note, but only the first kind should compete for sprint time against features and bug fixes that have a clearer, more immediate payoff for the business this quarter and the next.
For example, a team lists two items. One is an inconsistent naming scheme in a billing module nobody has changed in a year. The other is a missing test suite around the order flow that every feature this quarter touches. The naming issue is visible and irritating, but it costs almost nothing. The missing tests make each change risky and slow, so they go first. Log the naming issue, tag it as aesthetic, and revisit it at the next quarterly pass rather than letting it compete with features and bug fixes for sprint time.
How much engineering time should go to technical debt?
The teams that actually make progress on debt set aside a consistent share of engineering time for it, every sprint, and treat that time as non-negotiable the same way they'd treat a security fix. Teams that only address debt "when things slow down" never get to it, because things are always busy.
Whatever share you choose, the discipline of protecting it consistently matters more than the exact number. A team that skips debt work every time a deadline looms never actually pays it down.
Kill Debt Items That Aren't Worth Fixing
Not everything on the list deserves a fix. If an area is genuinely untouched, isolated, and working, the right call is often to formally remove it from the list rather than let it sit there as guilt. A shorter, honest list that the team actually works through beats a long, sprawling list nobody believes will ever get fully done.
Review the List Itself Every Quarter
Debt lists rot just like code does. An item that was critical eight months ago might no longer matter because the surrounding code was rewritten for unrelated reasons, and an item that seemed minor might now sit directly in the path of your most active feature work.
Set a recurring quarterly pass to re-score the whole list, not just add new items to the bottom. A list that only grows and never gets pruned stops being a useful prioritization tool and turns into background noise nobody trusts, which defeats the point of tracking it at all, and makes the whole exercise feel like busywork instead of a real prioritization tool the team actually trusts and uses when planning the next sprint.
Prioritize each item on the debt list with these questions:
- How often do engineers actually work in this area, compared with how bad the code looks?
- Is the debt structural, such as tight coupling or a missing test suite, or only aesthetic?
- Has deploy frequency dropped in this area without an obvious outside cause?
- Is the area untouched, isolated, and working, which makes it a candidate for removal from the list?
- Does the item still matter after the last quarter of unrelated rewrites in the surrounding code?
What Good Looks Like
Effective debt paydown prioritizes by how often an area is actually touched, tracks deploy cadence as an early warning signal, and protects a fixed share of time for the work every sprint.
Building The Capability (5-Stage Skill Ladder)
How to Get Started
Frequently Asked Questions
How do we convince leadership to invest time in technical debt?
Tie it to a metric leadership already cares about, usually deploy frequency or the time it takes to ship a typical feature. A concrete trend line showing things have gotten slower is far more persuasive than a general complaint about code quality.
Should we ever do a full rewrite instead of incremental debt paydown?
Rarely, and only when the current system is so structurally broken that incremental fixes can't reach the root cause. Full rewrites carry high risk and often take longer than planned. Incremental paydown, focused on the most-touched areas, works for the vast majority of situations.
How do we stop new technical debt from piling up as fast as we pay down old debt?
Add debt consideration to code review, not just feature correctness. Give reviewers explicit permission to flag "this adds debt we should track" and have it actually logged, not just mentioned in passing, which catches a lot of new debt before it accumulates unnoticed.
Sources
Where we quote a benchmark, we show its source. Other figures in this guide are estimates or general guidance, so check them against your own numbers.
- Deployment frequency by DORA performance cluster (max days between deploys). DORA Accelerate State of DevOps 2024 (Google Cloud), cluster table via Octopus Deploy analysis, 2024.
Related Guides
A Way to Prioritize Technical Debt That Isn't Just Vibes
Most tech debt lists never get funded because they don't actually rank anything. Here is a way to score debt by pain and blast radius instead of age.
A 30-Minute Audit for Finding Technical Debt That's Actually Costing You
A focused 30-minute audit for CTOs to find the technical debt that's actually slowing the team down, and the pitfalls that waste remediation effort.
A Way to Prioritize Pipeline Technical Debt That Isn't a Guess
A scoring approach for deciding which technical debt in a real-time data pipeline to fix first, instead of relying on whoever complains loudest.
The 30 Minute Technical Debt Audit Worth Running Monthly
A short, repeatable format for finding and prioritizing the technical debt that's actually costing your team time right now, instead of a shelved wish list.
Paying Down Technical Debt Without Stalling the Roadmap
A practical way to prioritize technical debt against feature work, decide what to fix now versus later, and avoid the rewrite that never ships.
A Triage System for Technical Debt That Actually Ships
A way to rank technical debt by blast radius instead of ticket age, so the fixes that actually prevent an incident get scheduled first.