Technical Debt and Inertia

Technical debt is one of those phrases that tend to rub me the wrong way.
Not so much the way it was defined originally by Ward Cunningham, but the thoughtless way in which it is being tossed around nowadays. Anything and everything that people don’t like is “technical debt”, much like anything and everything they like is “disruptive.”
 
Let’s look at the concept in a bit more detail to disentangle the threads, and to reveal the value that the analogy meant to offer.
The way I see it, there are three flavors we’re dealing with:
  • Useful Debt
  • Careless Debt
  • Cumulative Inertia
 

Useful Debt

This category is primarily what coined the phrase originally. You have a goal you need to achieve, such as shipping a new product by a certain deadline, or delivering a first iteration of a feature – yet you don’t have the resources needed to “do it quite right”. Sound familiar?
 
Cunningham compared it to the situation in which you need a house for your family, or perhaps a new machine for your factory. You can’t quite afford it with the means at your disposal, but it has clear value in the longer term and adds a tangible asset. That’s what a line of credit is there for: You borrow money to do something that adds value; you re-pay the money over time and if everything works out, you’ve made a gain at the end.
It is a risk, certainly, but a calculated one that you know and accept going into it. You plan your mortgage into your monthly spending, making sure you can afford it – and making sure to pay it on time.
 
Likewise, going into useful debt to ship a feature can be exactly the right thing to do. Time to market is crucial, and if “borrowing” e.g through initial use of a sub-optimal architecture allows you to shorten it, then that may be the way to go. So long as you do it with your eyes open, and with a committed plan to re-pay the debt by re-working the architecture in subsequent releases.
 
I’ve called it useful debt here because there’s nothing at all wrong with it – in fact it is the necessary lubricant that keeps the economy going. If everybody could only ever buy what they have the ready cash to afford right now, commerce would come to a grinding halt.
 
 

Careless Debt

On the opposite end of the spectrum, there’s what I call careless debt – expenses you put on your credit card not because they’ll provide any value in the longer term, but merely because you “feel like it” in the moment. The sumptuous dinner, the fancy suit, the tropical vacation.
Indulgence of this sort on the software development side comes down to – sloppiness. You’re trying to go fast not by taking calculated risks knowingly, but simply by not looking at things closely enough. Hope is your strategy: What could possibly go wrong?
 
Needless to say, this form of debt is more tempting, and hence more widely spread than the useful one. It is also more insidious since it comes in small increments. It’s this type of debt that Martin Fowler refers to as “cruft” that accumulates and slows down progress because it creates a lot of friction.
While useful debt has its purpose, as the term implies, careless debt really does not. It should and can be minimized through good engineering practices and coding discipline: clearly defining the use cases ahead of time, code reviews, good test coverage, and so on. Preventing careless debt from accumulating is much cheaper than having to pay it off later on.
 
 

Cumulative Inertia

The third variety isn’t really debt at all, even though the symptoms observed are very similar. In fact, it’s quite the opposite: an abundance of wealth.
When customers like your product, they want more of it; so over time you keep adding features and capabilities. The more there are, and the more they depend on each other (which they tend to always do), the smaller your room for manoeuvring – something that, in a different context, is referred to as cumulative inertia.
 
Even if something is built well at the time, it doesn’t mean that 5 years later it is still a great idea. As the world changes around a product, the product itself also has to adjust – hence the need for re-factoring, adaptation to new programming language capabilities, new architectures, and so on. It bears keeping in mind that this is a good thing, rather than a problem. If you need to re-factor your product code after a couple of years, it implies that it served a useful purpose during those years, that it enabled your business to be successful on its basis. Products that nobody wants, needs, or buys have no need for re-factoring.
 
 

In summary, there are different factors that can contribute to making software development on a product increasingly harder over time:
Useful debt, which you knowingly entered into for the purpose of time to market; careless debt which you incurred through lack of discipline in sloppy daily work; and cumulative inertia that is the result of successfully expanding your product over time.
In reality, of course, you’ll encounter an amorphous mixture rather than these cleanly separated phenomena: An architecture reasonable for something small, but now stretched to its limits by a slew of extra functionalities slapped on at odd angles, and with sometimes shaky implementations. Life is messy.
 
But only by keeping the flavors of technical debt separate in your mind can you devise the appropriate solutions.

Leave a comment