SoftwareMarch 30, 2026Updated on October 23, 20267 min readNano Concepts editorial team

Prioritizing Technical Debt: Pay the Interest or Pay It Down?

Technical debt is not a synonym for bad code – it becomes dangerous when it stays invisible. Here is how to assess legacy burdens by impact and effort and reduce them in a plannable way.

Featured image: Prioritizing Technical Debt: Pay the Interest or Pay It Down?

Technical debt means shortcuts and legacy burdens in software that make future changes more expensive – like a loan on which you keep paying interest. You prioritize it by assessing every item by impact and effort, dealing with security risks first and reserving a fixed share of your development capacity for paying it down.

Every software project accumulates legacy burdens over time: a quick fix shortly before launch, a postponed update, a module that only one person still understands. It becomes a problem when nobody knows how large the debt is. This article shows how to make it visible, assess it and anchor it in your plan – instead of watching a creeping slowdown.

What technical debt is – and what it is not

The debt metaphor comes from software developer Ward Cunningham, who coined it in the early 1990s: taking a shortcut means taking out a loan. That is legitimate as long as you plan the repayment – because every new feature takes a little longer and every bug is a little harder to find. Technical debt is therefore not a synonym for bad code. A startup that wants to test an idea may choose pragmatic solutions. What matters is that everyone involved knows where these shortcuts are.

Four kinds of debt

Martin Fowler’s classification is helpful; it sorts debt by intent and care:

IntentRecklessPrudent
Deliberate“We don’t have time for tests.” – quickly becomes a problem“We ship now and clean up afterwards.” – justifiable if documented and planned for
Inadvertentmissing basic knowledge of architecture and quality – can be reduced through reviews and training“Now we know how we should have built it.” – an unavoidable learning effect

Invisible debt is the real risk

  • Missing tests: changes become a gamble because nobody knows for sure what will break.
  • Unclear ownership: nobody feels responsible for core modules.
  • Outdated dependencies: libraries and frameworks lag several versions behind – including known security vulnerabilities.
  • Missing documentation: knowledge lives in heads instead of in the project.
  • Knowledge held by one person: if they are unavailable, the module stands still.

How to recognize technical debt in everyday work

Even without code analysis there are clear warning signs that management and business departments notice:

  • Small changes take disproportionately long.
  • Fixed bugs reappear in a new form.
  • The team avoids certain areas (“We’d rather not touch that”).
  • Updates are postponed again and again.
  • Releases become rarer and riskier because every delivery causes anxiety.
  • New developers take a long time to become productive.

Step 1: Make technical debt visible

What is not written down will not be prioritized. That is why we manage technical debt as separate, labeled items in the backlog – on equal footing with new features. Each item contains a short description, the cause, the concrete impact and a rough effort estimate.

We also record important architecture decisions in writing, so it remains clear later why something was built the way it was. Static code analysis tools help find hotspots – areas that are changed particularly often and are particularly complex at the same time. A dependency scan reveals outdated libraries and known vulnerabilities.

Step 2: Assess and prioritize technical debt

Not every debt has to be paid off immediately. We classify along two dimensions: the impact and the effort needed to fix it. Impact is mainly made up of these criteria:

  • Security: known vulnerabilities, missing updates
  • Availability: risk of outages in core processes
  • Development speed: how often the area is changed and how much extra effort each change costs
  • Knowledge risk: only one person knows the module
  • Requirements: data protection, contractual obligations or the end of support for a platform

The 2×2 grid

Impact / effortApproachExample
High / lowtackle immediately – the biggest benefit per hour investedupdate a dependency with a vulnerability, write tests for a critical module
High / highplan as a project of its own, budget it and implement it in stagesframework jump across several versions, restructuring a core module
Low / lowdo on the side – following the Boy Scout Rule: leave the code a little better than you found itinconsistent naming, dead code
Low / highaccept deliberately and documentcosmetic fixes in rarely used legacy areas

Security is an exception: outdated dependencies with known vulnerabilities take priority, regardless of effort.

A simple back-of-the-envelope calculation helps make the impact tangible: monthly interest ≈ number of changes in the area × extra effort per change. Suppose a module sees eight changes a month and each takes half a day longer because of missing tests – then the debt costs four developer days a month.

Step 3: Anchor the pay-down in the roadmap

Technical debt always competes with new features for capacity. To keep it from losing permanently, it needs a fixed place: a share of capacity agreed in advance in every planning round. As a rule of thumb, mature teams often reserve roughly a tenth to a fifth; that is not a standard, and for heavily burdened software it may temporarily be more. More important than the exact figure is that the share is binding and is not the first thing cut when deadlines loom.

The 2×2 grid helps justify such quarterly budgets to management. Argue in the language of the business: not “module X is ugly” but “changes to the ordering process take much longer than necessary” or “without the update we lack security patches”. That turns a technology topic into an understandable business decision. In addition, pay-down can be tied to features that are planned anyway: if you are touching the invoicing module anyway, secure it with tests first and tidy up along the way.

Example: the grown customer portal

A customer portal has grown over the years. The framework in use is several versions old, there are hardly any automated tests and only one developer still dares to change the invoicing module. New features take noticeably longer than they used to.

In the 2×2 grid, the framework update lands at the very top because of known security vulnerabilities. In parallel, tests are written for the invoicing module – with manageable effort and high impact, because they secure every further change. The restructuring of the module itself is planned as a separate project in stages. Cosmetic issues such as inconsistent naming are handled on the side. This noticeably lowers the interest without further development standing still for months.

Refactoring instead of a rebuild: small, safe steps

The most tempting mistake is the big rebuild. Complete rewrites often take longer than planned, and in the meantime further development either stands still or runs twice – in the old and in the new system. We rely on small, safe steps instead:

  1. First write tests around the affected area.
  2. Then restructure in small steps, each of which can be delivered on its own.
  3. Activate new implementations behind feature flags and switch back immediately if problems occur.
  4. Only remove old parts once the new ones run stably.

The same principle applies to larger replacements: with the so-called strangler fig pattern, individual functions are replaced step by step with new parts until the legacy system has nothing left to do. A rebuild is only justified if the technology is no longer supported, hardly any specialists can be found for it or the architecture fundamentally prevents key requirements – and even then the replacement usually works better in stages. Whether splitting into individual services makes sense is covered in the article Microservices or monolith.

Preventing new debt and a checklist

Technical debt cannot be avoided entirely – but it can be managed. A binding Definition of Done with tests and documentation, regular code reviews, an automated test pipeline and automatic dependency updates, for example via Dependabot or Renovate, keep debt from growing unnoticed. What this looks like in everyday agile work is shown in the article on Scrum in software projects. Ongoing upkeep is part of it, too: if you apply updates regularly, you avoid big jumps – which is what a maintenance contract regulates.

Checklist: technical debt under control

  • Debt recorded as separate backlog items with impact and effort
  • Assessment by security, availability, development speed and knowledge risk
  • Prioritization in the 2×2 grid, security issues first
  • Fixed capacity share for pay-down in every planning round
  • Refactoring only with tests and in small steps
  • Definition of Done, code reviews and dependency updates as protection against new debt

How Nano Concepts can help

Do you suspect that your application is progressing more slowly than it should? As part of our technology consulting we assess the state of your codebase and develop a realistic pay-down plan – optionally followed by maintenance and further development. In the free initial consultation you describe the situation to us, after which you receive a transparent quote.

Frequently asked questions

No. Deliberate shortcuts to reach the market faster are legitimate as long as they are documented and tracked. The problem is invisible debt, such as missing tests, unclear ownership or outdated dependencies, where nobody knows how expensive it will become.

Start with the everyday warning signs: long turnaround times for changes, recurring bugs, postponed updates. A dependency scan, static code analysis for hotspots and conversations with the team add to the picture. Record the result as backlog items with impact and effort.

As a rule of thumb, mature teams often reserve roughly a tenth to a fifth of their capacity for refactoring and reducing technical debt. That is not a standard: for heavily burdened software the share may be temporarily higher. More important than the number is that the share is firmly anchored in every planning round.

Rarely. Complete rebuilds often take longer than planned and block further development. It is usually more sensible to secure the existing system with tests and restructure it in small steps – for example with the help of feature flags. A rebuild only pays off when technology or architecture fundamentally prevent key requirements.

Translate the technology into business impact: how many extra days does a change request cost, what risk of outage or security breach exists, which knowledge hangs on one person? In that language, “module X is ugly” becomes an understandable investment decision with a clear benefit.

Matching services

Terms from this article, briefly explained

Sebastian MandlmeirNano Concepts editorial teamPractical expert articles – published under the responsibility of Sebastian Mandlmeir, Managing Director

More articles

Get the right quote in 60 seconds

Needs analysis: Prioritizing Technical Debt

Answer a few short questions – we usually get back to you within 24 hours with an initial assessment.

Request a project