Previous month:
September 2018
Next month:
January 2023

July 2019

All Technical Debt is Credit Card Debt

When you find yourself in the position of trying to persuade someone who doesn't share your life experiences, you may reach for a common metaphor. This metaphor becomes something that you can use to create a frame of reference...a set of facts that are independent from the actual facts because the actual facts are too complex or obscure to communicate.

In programming, perhaps the best example of this is technical debt. This metaphor has been misunderstood, misappropriated, and generally misused almost since it's inception. Why? Because it's so very useful! People who pay for software projects often have access to money, and people who have access to money often understand debt. So "technical debt" becomes a common frame of reference between holders-of-cash and writers-of-code, even if the participants in the conversation don't have a clear definition of what "technical debt" means. That lack of clarity leads naturally to creatively extending the metaphor. If you use this metaphor often, you may one day find yourself arguing with someone about whether a particular bit of crufty code is "long term debt" or "short term debt" or "high interest debt" or "low interest debt". If you work in finance, you may even push the metaphor into more esoteric instruments like convertible bonds or interest rate swaps. Maybe you've even created clever systems for tracking debt or measuring debt, adding in additional metaphors like "interest rate" and "payment terms".

When this happens to me, I start pushing back. That's because, after using this metaphor for years, I've found that all these creative extensions of the metaphor only serve to obscure the issue at hand, which is: We wrote some code that doesn't fit our current understanding of the problem, and now we should change it. Of course, that sort of argument doesn't usually play well with others, so instead of decrying the extension of the metaphor, I simply pick the best one and go with it, which is:

All technical debt is credit card debt.

When you use a credit card to buy something that you can't afford, you generally tell yourself that you will pay it off "soon". Every once in a while, you make a conscious decision to buy something with a credit card and not pay it off for a while. And every once in a great while, this turns out to be a good idea in retrospect. But usually, when you use high-interest credit to buy something you can't afford, you're making a promise on behalf of your future self to go without something else that you might otherwise want to buy (with interest), which reduces the total area under the things-you-want curve.

When you buy something that you can afford with a credit card, that's a completely different thing. You're just playing a little game with short term cash flow. Your credit card company gives you a grace period of somewhere between 30 and 60 days between when you buy a thing and actually have to pony up the cash. Additionally, carrying around a little plastic card is a lot easier (and safer) than carrying around all that cash. So you buy things with your credit card, and pay the bill in full every month.

On healthy software development projects, some amount of "grace period" debt is expected. It appears as a side effect of building software. Small experiments create small amounts of debt which is refactored when the experiment is over. Decisions are deferred for a few minutes, hours, or days...until a design starts to take shape. Code is left ugly or slow until it's proven to work with tests, and then cleaned up once the scope and scale of problem is well understood. Effective programmers have a good internal sense of when to shift back and forth between getting things done and cleaning up small messes.

If the team cares about the quality of their work, you won't ever have to tell them to pay off this "grace period" debt...indeed, you probably won't even see it, let alone track it or direct them to clean it up. So it won't ever be tracked on a card wall, discussed in planning meetings, or documented on a wiki. However, since only the programmers have visibility to what debt has actually been accrued, you have to trust them to decide when it's appropriate to pay off debt, and when it's appropriate to work on new functionality. Trying to shift responsibility for making that decision away from the folks who have their hands in code every day changes the conversation from "pay it off in full every month" to "how many months of interest should we pay?" Most of the time, this is a bad idea.

Just like a credit card, if you don't pay off debt during the grace period, it can quickly spiral out of control. The more debt there is, the less money (time) there is to pay it off due to the interest payments. Just like the poor souls whose financial lives have been crushed by credit card debt, eventually all your income goes to interest payments and there's nothing left over at the end of the month. This will often manifest as a "critical mess", where making the changes to fix one bug creates two more bugs. Your programmers will then start to fear making changes to the code. They may suggest a rewrite. Or maybe they'll just quit. In either case, once this happens the code becomes effectively impossible to change, and your accumulation of technical debts means you'll have to declare technical bankruptcy.