Technical debt: how a client can tell a system is accumulating problems, and what it costs
What technical debt means in a custom system in the client's own terms: the signs you can see without reading code, where it comes from, how much time to set aside for working it off, and when a rewrite is justified.
Short answer: technical debt is decisions that were taken faster than they should have been, and that you keep paying for with every new change. A client can see it without reading any code: simple changes now take weeks, every fix breaks something next to it, developers do not want to update libraries. The usual arrangement is that part of every work stage goes on paying it down. Rewriting the whole system is rarely necessary, and that decision belongs after an audit, not before it.
Where it comes from
Part of the debt is taken on deliberately. Before a launch the date matters more, so something is done temporarily: a direct query into the database instead of a proper exchange, a copy of some code instead of a shared module. That is a fair trade as long as somebody closes it later.
Another part accumulates on its own. Requirements change, and old code is bent to fit the new ones instead of being reworked. A couple of years later the system has three ways of doing the same thing and nobody remembers which one is authoritative.
A third part simply comes with time. Libraries and the platform release new versions, and old ones stop receiving security fixes. Leave them long enough and the update becomes a project of its own.
The signs you can see without the code
Simple changes get expensive. A new field on a form is estimated at a week. A year ago it was a day.
Fixes break the things next to them. After every release, bugs surface in places nobody touched.
One person knows how it works. When they are on holiday, changes wait.
Updates keep being postponed. Developers say that updating versions is risky, and it slides from quarter to quarter.
There are no automated tests. Pre-release checking is done by hand, and every release becomes an event.
How much time to set aside
The arrangement that works: in every stage of work, part of the developers’ time goes on the debt. Every fifth task, say, removes something that is slowing new features down. The vendor should be able to say what exactly they are fixing and what it will do for the changes that follow.
Library and platform updates belong in support rather than in the debt budget. There is more on that in what support after launch costs.
When a rewrite is justified
Every new developer who opens somebody else’s code wants to rewrite it. That is usually more expensive than it looks: the old code holds years of fixes and exceptions that are written down nowhere.
A rewrite earns its place when the platform is no longer supported and there is no upgrade path, when the system cannot carry the load because of how it is built rather than because of a few slow places, or when the business has changed so much that most of the system now does the wrong thing. Even then it is better done in parts, with the old system still running.
Common questions
How do I know the vendor is being straight about the debt? Ask for a list of specific places, with an estimate of how much time each one costs on changes today. General statements about bad code mean nothing.
Is there debt in a brand-new system? Almost always, especially after a fast launch. That is fine as long as the vendor knows where it is and has written it down.
Can we just not spend money on this? For a while, yes. Then every change gets more expensive, and you pay for the debt anyway, invisibly and with interest.
The rule
Watch what changes of the same size cost over time. If they get more expensive year on year, the system is accumulating debt, and paying it down needs a standing share of developer time.
Related reading
Facing a similar problem?
Tell us what you are building. We will walk through the architecture and give you a budget range in one call.