Almost all communication between developers and non-technical colleagues or clients is done through a set of metaphors. Some of them (the construction metaphor, for example) are actively harmful, but others are potentially very useful.

The idea of technical debt is one of these but, as with any metaphor, it’s important to understand where the limits of its applicability are. For these metaphors to be useful, they need to be used accurately.

There’s a pronounced tendency within the agency world to appropriate technical terms and then to use them incorrectly (‘operating system’ is the trope du jour), presumably in order to appear more technically knowledgeable but, to anyone who knows what these things really mean, the effect is just to reveal the metaphor abuser as a bullshitter.

Abused in this way, useful terms gradually become stripped of their meaning and replacements have to be found. I worry that this is happening with the term ‘technical debt’. Hopefully, this post will help to clarify its meaning.

According to Wikipedia, Technical Debt is “a neologistic metaphor referring to the eventual consequences of slapdash software architecture and hasty software development”. As with financial debt, this is often unavoidable and the results can eventually be paralysing if not properly identified and dealt with.

All projects incur technical debt, and that’s no bad thing. A project without debt is treading too carefully and almost certainly incurring waste. In a lean project, especially, it would be a mistake to produce debt-free code at all times. A more sensible approach would be to test a hypothesis by executing it as quickly as possible and learning from the real use of the system. Only if users like the new feature would it make sense to pay down the debt.

Paul and I were chatting about this the other day, and I came up with what I described as four ‘grades’ of debt.

Grade One: Accumulated debt over time due to framework changes

If you’re developing software in a sensible way, you’ll be building on top of others’ work using frameworks – such as Ruby on Rails – that are widely understood and supported. One of the features of such frameworks is that they change, because the only alternative is atrophy.

In a healthy framework, these changes make it more simple, more secure, faster, easier to maintain, more flexible and more feature rich. The tradeoff is that they often break backward-compatibility, so unless your development team makes the effort to adopt the new features, you gradually incur debt. Why?

It’s almost inevitable that a framework will improve to the point that you want to adopt the newer versions, even if it’s simply to apply a security patch. If you don’t keep a keen eye on these changing foundations and keep your codebase relatively up-to-date, it will become more and more difficult to adopt the newer versions. Maybe someone will release a new plugin, or build some integration with a new social service that you’re keen on. But who’s going to take the time to write code to support it on older versions of your framework?

This kind of debt is the least damaging kind, and can easily be avoided by adopting a sensible upgrade strategy. It’s not enough to simply upgrade the underlying platform, though; you also need to take the time to make sure your system adopts the new idioms of the updated framework so that it can take full advantage of the new features.

Grade Two: Developers making themselves feel more comfortable

One of the skills you need to acquire in order to be a great software developer is the ability to work with code written by someone else. Anyone can come along and rewrite a system from scratch, but only great developers can do a really good job of maintaining someone else’s code.

Many developers don’t like doing this, and you’ll often hear them saying that the codebase has too much technical debt and needs to be rewritten. This is a bit like saying that the windows in your house are dirty, and so the building needs to be knocked down and rebuilt.

In my experience, at least 99% of the time you’re told that something needs to be rewritten from scratch, you’re just being told that the developer is too lazy to be bothered to understand someone else’s code.

You’d do better to ignore such advice, and just get better developers. Instead, concentrate on the other three grades of debt.

Grade Two debt is almost always phantom debt.

Grade Three: The legacy of pragmatism

The reality of developing software professionally is that there is never enough time to do a perfect job. Sooner or later, you’ll have to hold your nose and implement something in a less than ideal way in order to meet a deadline or a budget.

Just like manageable debt in real life, this isn’t toxic. Often you can afford to compromise on quality, but knowing when is a trait that only good developers possess.

Here’s the key thing about healthy Grade Three debt: the cost of implementing a feature in a sub-optimal way is the cost of doing it twice, once to meet the deadline and once to reimplement it in a more sustainable way.

If you fail to pay down the debt in a reasonable timeframe, then you’ve done the equivalent of shoving the red credit card bill in the recycling. And, sooner or later, you’ll end up with Grade Four debt.

Grade Four: Impossible to move forward

Grade Four is the sub-prime mortgage of technical debt.

Accumulate enough Grades One or Three debt, and you’ll find that it becomes almost impossible to add new features to an existing system in a timely way. You’ll probably also find that you have many more bugs in your system than is acceptable, and you’ll spend more on operational maintenance too. By this stage, your users will probably have started to notice errors, security holes or performance problems.

These things are the cost of servicing the debt, like the interest on your credit card; you still need some way of paying off the principle.

Obviously, this is a situation that you should strive to avoid, but it’s all too common. That’s because people fail to account for the cost of paying down the debt they have accumulated over time. It feels good to add features, just as it feels good to go on a shopping spree, but as with your domestic finances, discipline is its own reward in the long run; you’ll be able to afford to spend more of your money on new features over time if you pay off your debts in a sensible fashion, you just won’t be able to do it straight away.

If you find yourself in this situation, it’s sometimes tempting to ask yourself if it’s worth starting again from scratch, but that’s an extreme reaction to the problem, the equivalent of declaring bankruptcy. Far better to create a structured plan for paying down the debt over a reasonable period of time.

If carefully managed, the result can be an all-round improved system, which is cheaper to support and iterate on, and happier users to boot.

James Higgs

James Higgs

James has been developing software commercially for almost 20 years, in fields as diverse as manufacturing, TV broadcasting and retail. For the last decade and a half, he has focused almost exclusively on the web. Today he is increasingly fascinated with mobile devices, in particular Apple's iOS devices.

@higgis