How to Reduce Technical Debt

How to Reduce Technical Debt Without Slowing Delivery

Author Image

Bertoni Solutions Team

Jul 6, 2026
Jul 6, 2026

The short answer to how to reduce technical debt without slowing delivery is to stop treating repayment as separate work. You pay it down inside features you have already committed to, along the specific code paths those features touch, and you never ask the business to approve a cleanup project.

Most teams try the opposite. They negotiate for a share of every sprint, lose that share the first time a deadline gets tight, and conclude that the business does not care about engineering quality.

The business is not the problem. A cleanup budget with no decision rule attached is the problem, because it gives engineers permission to improve code without telling them which code. So which code actually deserves the effort, and how do you pay for it inside a roadmap that is already committed?

Start with what the debt is costing you right now, because that number decides everything downstream and it is rarely the number teams think it is.

What technical debt actually costs you

Technical debt is the gap between how your system is built and how it would be built if you started today with what you now know. The principal is the work required to close that gap. The interest is what you pay every time you change the system while the gap is still open.

Only the interest matters for planning. Principal sitting in code that nobody modifies costs nothing at all, which is the single most useful fact in this entire discussion.

McKinsey has reported that CIOs estimate technical debt at 20 to 40 percent of the value of their technology estate before depreciation. That figure is useful for a board conversation and almost useless for a sprint conversation, because it measures principal across everything rather than interest on what you are about to change.

Interest shows up in specific, observable ways:

  • A two-line change requires edits in six files because logic is duplicated
  • Nobody will deploy on a Friday, so releases queue up and get larger
  • A new software developer takes eleven weeks to become productive instead of four
  • Estimates on one part of the codebase are consistently wrong by a factor of two
  • The same bug class reappears every few months in a slightly different place

Each of these has a cost you can measure in engineering hours. That is what you build the case on, and it is far more persuasive than a percentage of estate value.

Why the twenty percent sprint rule fails

Most advice on how to reduce technical debt starts by reserving a fixed slice of capacity, usually twenty percent, for technical work. It is popular because it sounds disciplined and it requires no analysis.

It fails for a structural reason. A fixed percentage is a budget, and budgets are the first thing cut under pressure, so the allocation disappears in exactly the quarters when the codebase is being changed fastest and accruing interest quickest.

It fails a second time even when it survives. Given unallocated cleanup time and no priority signal, engineers reasonably improve the code that bothers them most, which is frequently code they find ugly rather than code the roadmap is about to hit hard.

The result is a team that spent real capacity on refactoring and still cannot ship faster, because the improvements landed in the wrong places. That outcome then gets used as evidence that paying down debt does not help.

The premise behind the quota is worth questioning too. Years of DORA research into software delivery performance have found that speed and stability improve together rather than trading against each other, which means the teams shipping fastest are generally the ones with the healthiest codebases rather than the ones who bought pace with debt.

How to reduce technical debt by mapping change frequency

Pull the commit history for the last twelve months and count how often each file or module changed. Any engineer on your team can do this, and it does not need a consulting engagement to produce. Then rank your known problem areas by that count rather than by how much the code offends anyone.

This single exercise reorders most backlogs. Teams routinely discover that the module everyone complains about has not been touched in fourteen months, while the quietly awful integration layer changes every second week.

The rule follows directly. Repay debt where change frequency is high and the roadmap says it will stay high, leave debt alone where change frequency is near zero, and revisit the list each quarter as the roadmap moves.

Stable, ugly, working code is not a liability. It is a solved problem that happens to look bad, and rewriting it converts a zero-cost asset into schedule risk for no delivery benefit.

Build the ratchet before you repay anything

Before you change a single high-churn file, make sure the change is safe to ship and the improvement cannot be undone. Teams that skip this step repay debt for two quarters, watch it return, and conclude that cleanup is pointless.

The mechanism that prevents return is a ratchet: automated checks that make the current state the new floor. Coverage on modified files cannot fall, linting and static analysis run in continuous integration rather than on request, and the build fails rather than warns.

Three specifics matter more than the rest of the tooling conversation:

  1. Test coverage on changed lines only. A global coverage target invites gaming and demoralizes teams working in legacy code. Requiring coverage on lines the current change touches is achievable and compounds automatically.
  2. Deployment automation before refactoring. Teams that cannot deploy safely will not refactor, because every change carries release risk. A cloud specialist is often the faster route here than retraining the product team. Fixing the pipeline first is what makes everything after it possible.
  3. Architecture decision records. Most debt was a reasonable choice under constraints nobody wrote down. Recording the reasoning stops future teams from rediscovering it through failure.

None of this ships a feature, which is exactly why product teams defer it indefinitely. The harness and the pipeline are a one-time build that every future repayment depends on, and they make the strongest case for outside hands rather than pulling your best engineers off the roadmap.

Bertoni's software engineering support covers this work directly, from test harness and pipeline construction through backlog execution. In practice that means QA engineers and DevOps engineers working inside your repository and your review standards rather than handing over a report about them.

Independent software testing support serves the same purpose when the gap is coverage rather than pipeline.

Attach repayment to work already scheduled

Here is the mechanism that keeps delivery speed intact. Every feature that touches a high-churn area carries its own remediation inside the same estimate, scoped strictly to the paths that feature uses.

If a story requires changing the billing integration, the story includes bringing that integration under test and extracting the duplicated logic it depends on. The estimate goes up. Nothing gets added to the roadmap, and nobody has to approve a refactoring initiative.

That estimate increase is the whole objection, and it is worth being direct about. The roadmap does not move and no cleanup project appears, but individual stories cost more, and the first sprint where that collides with a committed date is usually the sprint the practice dies.

Teams that sustain it do one of two things. They lower their commitments for a quarter, or they add engineering capacity to absorb the difference so the roadmap never feels it.

The discipline is in the scope. You fix the road you are driving on, not the whole map, and you resist the pull to keep going once you are already in the file.

For larger structures, the same logic scales into a strangler approach. New functionality goes into a clean component alongside the old one, traffic moves across in stages, and the legacy path is removed once it carries nothing, which is how most successful application modernization work actually proceeds rather than through a rewrite.

Decide what you will never repay

Not all debt should be paid. Some systems are close enough to end of life that the correct decision is to write the debt off and stop investing.

Three categories qualify. Code scheduled for decommission inside eighteen months, code supporting a product line being wound down, and code that works, does not change, and has no upcoming roadmap contact.

Cloud migration changes this calculation, since moving a workload forces contact with code that was otherwise dormant. Where that applies, Azure development work and the remediation it triggers should be planned as one item rather than two.

Say so explicitly and record it. An unwritten decision to ignore a system gets rediscovered by every new engineer as a surprise, and the team spends the same energy relitigating it every six months.

Writing debt off is also the fastest way to shrink the list. Most backlogs contain a substantial share of items nobody will ever act on, and removing them makes the remainder credible.

Make the interest visible before you ask for anything

Engineering leaders lose this argument by describing the problem in engineering terms. Duplication, coupling, and missing test coverage are all real, and none of them appear in any conversation the executive team is having.

Convert to time and money instead. Track how long changes take in the high-churn areas you identified, how much of each release goes to fixing the previous release, and how often work in those areas overruns its estimate.

Two numbers usually carry the whole case. The first is the ratio of time spent changing existing behavior to time spent building new behavior. The second is the share of engineering hours consumed by unplanned rework in the last quarter.

When those numbers are on a slide, the conversation stops being about code quality and starts being about throughput. That is a conversation the business already knows how to have.

Where the extra capacity comes from

The honest constraint is that attaching remediation to features raises estimates. Velocity on new functionality drops for a period before the throughput gain arrives, usually one to two quarters in.

Most organizations cannot absorb that dip while the roadmap is under commitment, which is the real reason technical debt persists. The engineering case is understood and the capacity does not exist.

Added capacity changes the arithmetic rather than the argument. Three engagement structures fit this work, and the differences between them matter more for remediation than they do for new development:

  • IT staff augmentation. Engineers join your existing team and carry the remediation stream while permanent staff hold roadmap pace. The two never compete for the same sprint, which is the entire point.
  • Dedicated team. The same engineers stay on the codebase long enough to learn why it was built the way it was. Better suited to a sustained program than to a single cleanup push.
  • Software development consulting. Where the debt is structural rather than local, the sequencing decision matters more than the headcount, so the analysis has to come before the hands.

Whichever structure fits, proximity decides how well it works in practice. Bertoni's engineering teams fill this gap where the internal team is at capacity and the work with no external deadline attached is the work that keeps getting dropped.

Our nearshore development engineers work United States business hours from Latin America, join your standups, and follow your review standards. That matters more here than on greenfield builds, because repaying debt depends on understanding why the code is the way it is, and that understanding comes from conversation with the people who wrote it rather than from documentation.

Starting this quarter

How to reduce technical debt comes down to targeting before capacity. Rank your codebase by change frequency, measure the interest you pay in the top few areas, and attach repayment to features already heading there.

Then build the ratchet so it does not come back, and write off the debt you have privately decided to ignore. None of it requires pausing the roadmap, and none of it requires a digital transformation program to authorize it.

If your roadmap has no room for the estimate increase, the constraint is capacity rather than strategy. Schedule a consultation and we will look at where your interest is actually accruing and what it would take to service it without pausing delivery.

Written-By-Human-Not-By-AI-Badge-white-1

 

Frequently asked questions

How do we measure technical debt without a formal audit?

Use commit frequency against defect density per module. High-churn files with recurring bugs are where interest accrues. This takes an afternoon with your version control history and needs no tooling purchase.

Should we refactor or rewrite a legacy system?

Rewrite only when the platform is unsupported or the business domain has fundamentally changed. Incremental replacement behind a stable interface carries far less delivery risk and produces value throughout rather than at the end.

Who should own the technical debt backlog?

Engineering owns identification and sequencing, product owns the trade-off against features. Splitting it this way prevents both a cleanup wishlist with no business case and a roadmap that ignores throughput decay.

How do we stop new debt while shipping fast?

Automated gates in continuous integration, coverage requirements on changed lines, and mandatory code review. Speed comes from safe deployment, so prevention costs less delivery time than most teams expect.

Can external engineers work on unfamiliar legacy code?

Yes, with overlapping hours and access to the original authors. Context transfer happens in conversation, which is why time zone alignment matters more for remediation work than for new development.

Digital Transformation

You might also like...