The Trouble with Tech Debt

May 29th 2019

Note: A friend of mine recently co-authored a book, Managing Technical Debt, and if you're a developer or architect wrangling with instability or quality issues, it's a really great read. They kindly asked me to contribute a side bar. In this post, I'm poking at the limits of the standard definition, but I think they've got some great answers/insights in their book.

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?

I'm an "old" programmer who has been blogging for almost 20 years now. In 2017, I started Highline Solutions, a consulting company that helps with software architecture and full-stack development. I have two degrees from Carnegie Mellon University, one practical (Information and Decision Systems) and one not so much (Philosophy - thesis here). Pittsburgh, PA is my home where I live with my wife and 3 energetic boys.
I recently released a web app called TechRez, a "better resume for tech". The idea is that instead of sending out the same-old static PDF resume that's jam packed with buzz words and spans multiple pages, you can create a TechRez, which is modern, visual, and interactive. Try it out for free!
Got a Comment?
Comments (4)
June 04, 2019
Hey Northrop!

When it comes to facing technical debt as a small team catering to a client, which is the crux in exhibiting the importance of “paying back the debt” to the client:

1. Finessing the relationship with the client (interpersonal tasks)
2. Attempting to define the debt in terms of time saved now vs. time wasted later? (analysis)

June 04, 2019
Thanks Bassman! Yeah...your 2nd point is key. Explaining to a client that some "tech debt" work needs to be done now so that we can save money in the long run is important...and in that way, the metaphor of "tech debt" is really useful.
September 16, 2019
I like to define tech debt as any code that bloats a system or slows it down. Implementing inferior solutions speaks more to the architecture. Did the architect get it wrong? If you are using junior devs instead of senior and they totally ignore the advanced features of a language to implement code than sure I can see that being debt too. I think the tech stack upgrade like with angular is more often to occur. Or using too many solutions together like struts, spring, hibernate, sql, ect. If you are making requests and too many things are happening you have some debt. A database should be normalized, and a system should serve its function as expected. When you are speaking of deadlines, it sounds like management is forcing a solution before any has been designed so the developers are just coding from stackoverflow as quick as possible. That is what I imagine. Thoughts?
September 26, 2019
Thanks @Jho. Interesting points. I think that's probably the right approach, don't get too pedantic about it (as I did in this post!).

As you said, tech debt is "any code that bloats the system or slows it down". Whether you implemented it knowingly or unknowingly doesn't's still a debt we need to repay.