Technical debt: what it is and how to reduce it
When an application is new, adding a feature is quick. A couple of years later the same size of change takes three times as long, and after every release something has to be fixed that nobody touched. The developer says "that's hard to change", and nobody can quite explain why.
This has a name: technical debt. It is the sum of all the shortcuts that were once taken to get something done faster and were never cleaned up afterwards. Like financial debt, it accrues interest: the longer it sits, the more expensive every next change becomes.
Where technical debt comes from
Technical debt is not necessarily a sign of bad work. Often it was a deliberate and sensible decision: the product had to reach the market before a competitor, the deadline was fixed, or it was not yet clear what users actually needed. The problem starts when the shortcut becomes the permanent solution.
The most common sources:
- Outdated components. The framework, libraries and server software are several versions behind. Every skipped update makes the next one bigger and riskier.
- Copied code. The same logic exists in five places, each slightly different. A fix in one place doesn't reach the others.
- Missing tests. Nobody can check before a release whether a change broke something elsewhere.
- Undocumented decisions. Why is this table structured this way? Why does this function call three others? The answer left with the developer.
- Temporary solutions. "Let's do it this way for now and fix it later." Later never came.
How to recognise technical debt
You don't have to read the code yourself to notice the debt. The business symptoms are often clearer:
- Estimates stretch: "this will take two weeks" turns into six.
- Bugs appear faster than they are fixed.
- A new developer needs months before they dare to change anything.
- There is a part of the system nobody wants to touch.
- Security updates aren't installed because "it might break something".
If three or more of these apply, the debt is probably already larger than the budget for new development.
How to measure the debt
Technical debt can't be calculated precisely in euros, but it can be mapped. In a review I go through:
- The age of the components. Which frameworks and libraries are out of support, and which have known security vulnerabilities.
- The risk areas. The parts where changes cause the most bugs and which are changed most often. That is where fixing pays off most.
- The dependencies. What calls what, and whether replacing one part requires changing ten others.
- The state of tests and documentation. How much of the system can be checked without clicking through it by hand.
The result is a list where each problem has its risk, impact and estimated effort. From that you can decide what to do now and what can wait. How the review works in more detail is described in the post on software audits.
How to reduce the debt without stopping the business
The most common mistake is deciding to "rewrite the whole thing". A working system contains business rules accumulated over years that no specification describes. A rewrite has to rediscover them all, and in the meantime the old system still has to keep running. When a rewrite does pay off is covered in the post legacy software: modernise or rebuild.
A step-by-step approach is more sensible:
- Start with security. Unsupported components and known vulnerabilities before anything else.
- Fix where you are already working. If a new feature touches a module, tidy that module at the same time. That way the debt shrinks where it actually costs you.
- Add tests before changing. First tests around the risky part, then the change. That way you see immediately if something broke.
- Replace part by part. An old module is replaced by a new one until all parts have been swapped. After every step you have a working application.
- Document as you go. Every decision is written down, so the next person doesn't have to start from scratch.
How much time to give to reducing debt
A good rule of thumb is to reserve part of every development cycle for clean-up, instead of leaving it as a "some day later" project. If the debt is already so large that new features can't be added in a reasonable time, a separate modernisation phase is needed. For a while there will then be more clean-up than new development.
Summary
Technical debt is normal, but it must not grow out of sight. Map it, start with the highest-risk parts and reduce it step by step, so the business doesn't have to wait.
If your application has reached the point where every change is expensive and risky, see how I handle software modernisation and further development, or describe your situation. I'll tell you honestly whether the application is worth tidying up or whether it makes more sense to build something new.
