At first, the metaphor of technical debt seems so crisp and clear. It's the perfect way to explain to your manager, product owner, or fellow developers the impact of all the copy-and-paste code you see in the code base or those horrible thousand-line functions nested 8 levels deep.
"In order to make that last release, we had to cut a few corners. These cut corners are like 'debt' , and at some point we'll have to pay it back or we'll go bankrupt"
At this level, the concept of technical debt is absolutely effective. Everyone gets it. Just like any individual person, a software development team too needs to manage their "finances". Sure, it may be ok to take out a line of credit to "build that addition" (or whatever), but as a standard way to operate it's not sustainable. Pay now, or pay later.
So what's the problem?
The devil is in the details, as they say, and although the metaphor of "debt" makes a lot of sense at the conceptual level, things get fuzzy real quick when you try to put your finger on exactly what it is. This matters because when it's difficult to define something, it's really tough to measure or manage it, and this is exactly what we want to do with technical debt. Once we accept that we have this "debt" in our systems, we naturally want to know how much we have, whether that's a lot, and how long we have until the bank repossesses our system. The trouble is, there are so many different interpretations of technical debt, this is anything but trivial.
Sure, there is a consensus definition that seems tenable and intuitive at a high-level, but it frays with just a little scrutiny. To see what I mean, let's start with the standard definition of technical debt. Paraphrasing from the Wikipedia:
Technical debt is the cost of additional rework caused by choosing an easy solution now instead of a better approach that would have taken longer.
The first thing to note is that taking on debt is a decision we make. A deadline looms, and so we consciously choose expedience over "doing the right thing". We've all been there, and calling this "debt" is an apt description.
But wait. Is it always a choice? What about those cases where we unknowingly implement the inferior solution? Maybe we were new to the language or framework, and had no idea there was a better way. Or maybe we were just genuinely clueless! Martin Fowler considers this technical debt also, but classifies it as inadvertent debt. Ok, so now tech debt isn't necessarily a conscious choice, but it is still something we do to ourselves...
But maybe not (!), because it's easy to think of cases where it wasn't our doing. For example, what if we were moving along merrily and then some underlying framework we were using changed, and we now need to upgrade or migrate (AngularJS anyone?). Some call this accidental debt - it's something we have to address and it'll get worse the longer we wait, but it definitely wasn't a choice - it happened to us because of age or decay. But again we're further away from the original definition...
And then is tech debt only about maintainability? Could it be related to any "ility"? For example, if I quickly bang out some naive/slow algorithm but add a // TODO fix this to make it faster, is that tech debt? It seems to fit the criteria of expedience over doing what's "right" in the long run, but it's about performance and not maintainability. And if this too is technical debt, why couldn't we consider some sub-optimal solution for security or resilience tech debt as well (e.g. the system doesn't handle failure now, but could with some rework)? And while we're at it, is lack of code comments tech debt? Or lack of documentation in general? And so on and on...
Maybe this seems like pedantic nit-picking...but that's kind of the point! As we ask reasonable questions about what technical debt is and what it is not, we stretch at the seams of the concept in general, and it begins to unravel to the extent that it seems like either everything is tech debt, or nothing is tech debt (a position held by some) and at this point the entire term can seem almost vacuous.
So where does this leave us? I think there are a few options. One is to just admit that the more we allow for new and different edge cases of technical debt (e.g. accidental debt, inadvertent debt, reckless, etc.), the more we water down the entire concept in general until no one really knows what it is, and it begins to lose its effectiveness as a metaphor. Just hold the line on the original definition and we'll be better off.
Another option though is to see it as just a metaphor, and then at a backlog/management level, treat all work as simply stuff that needs to get done to improve the system. Whether a given work item is there because we cut a corner a few months ago or because our version of Java is being sun-setted next month doesn't matter - it's just all work we need to prioritize and then do. Basically, use "technical debt" as an explanatory term, but at a practical level just manage it on your backlog with everything else.
In the end, I'm curious what you think. Am I missing a key distinction? How do you use the concept of technical debt? Is it helpful?