If you google the term Technical Debt, you’ll get a wide range of results back, each looking at the subject from different perspectives, be it Agile Development or Test Driven Development or whatever it might be.
Wikipedia says :
“Technical debt (also known as design debt or code debt, but can be also related to other technical endeavors) is a concept in software development that reflects the implied cost of additional rework caused by choosing an easy (limited) solution now instead of using a better approach that would take longer.”
Another definition from ProductPlan.com says: “Technical debt is the result of prioritising speedy delivery over perfect code”.
Atlassian says: “Technical Debt is the difference between what was promised and what was actually delivered.”
We get the sense that rushing software development is probably a factor, and that last definition leaves some room for non technical causes, although I would argue that what is needed at the time the software is being used is probably more important than what was promised at the start of the development project. I suspect they are coming from the perspective that technical debt somehow relates to the cost of fixing everything you need to fix to meet your promised solution, so in a contractual world maybe they have a point.
But are we really any wiser about what technical debt actually is? Can we use these definitions to point to something and say “There it is! That! That is the technical debt”?
To get to the bottom of all this I’m going to go back to the source.
The term Technical Debt was first introduced as a metaphor by Ward Cunningham in 1992 when he was explaining the trade off between development speed and re-work in creating software.
His original intent was to explain why it was sometimes necessary to start developing software early, in order to get feedback, before you knew the full requirements of the project.
In those days, waterfall development processes were common in software engineering, due to an ill-conceived parallel with traditional engineering practices. A major problem for software engineering projects at that time was analysis paralysis, where a huge amount of effort went into documenting requirements before development started, and many projects were cancelled before they were ever completed (this still happens today, but possibly for different reasons). The requirements that had been missed, or had changed since the initial analysis, would not come to light until the very end of the project in the user acceptance stage when they typically cost millions to put right.
Ward Cunningham said that Technical Debt was not supposed to be about poor code, and has expressed his frustration that the term was being used in this way. In his view, there was no excuse for poor code. According to him, technical debt was something that should be taken on, deliberately, for a good reason, and he was talking about building an incomplete product quickly to help resolve the problem of incomplete or unknown requirements, rather than taking shortcuts in code. You would take on the technical debt on knowing full well that you would need to go back later and fix the problems, add in the missing features, or change the ones you guessed incorrectly, based on the information you found out by building the first version.
So, if we explore the metaphor in more depth, we take on technical debt in order to get some benefit in the short term, in the same way as when you take out a mortgage in order to quickly buy a house so you can live in it. But in that situation, you know you need to make interest payments on the mortgage until it is paid off, and you know that if you don’t pay the interest or you don’t pay off the capital within the agreed term, your house will be repossessed and you will be evicted.
In the same way you might deliberately take on technical debt in your software in order to get a product to market quickly, or fix a bug that is causing a major issue for your customers, but you should do this knowing that you will be paying interest on this software until you pay off the debt by refactoring your software and implementing a more scalable or maintainable long term solution.
So, what is this Interest that you pay on Technical Debt? It is the extra time and effort that it will take you to make future changes to your code that you would have avoided if you were able to build the product the right way the first time.
If you don’t pay off the technical debt, it will cumulatively increase in your software over time, change on change, each change made on top of the bad code making it a little bit harder for the next time, until it takes so long to make a change to your code, that you cannot afford the developer and tester hours to do it.
With interest payments in mind, the Definition of Technical debt that I like best, for it’s simplicity and completeness is this one from the book “Software Design X-Rays” by Adam Tornhill. He says simply:
“Technical Debt is code that is more expensive to maintain than it should be”
After all, if something is making your software maintenance more expensive than it should be, that is like paying interest on a financial debt. Our concern as software professionals is to reduce these costs, so we need to look at all the factors that are increasing the production and support costs of our software, so we can identify which ones are hurting the business the most and focus on those.
So the short answer to the question “What is technical debt” is, “Technical Debt is code that is more expensive to maintain than it should be”. It’s code that you’re paying interest on.
Furthermore, I’m going to disagree with Ward Cunningham on this, and say that poor code is a cause of Technical Debt, as it most certainly increases the cost of future development of the software product but it is absolutely not the only cause.
I like this definition because you can use it to look at an issue and say, yes, that is technical debt because it is costing us extra money to maintain our software – or no, that is not technical debt because although it’s a bit ugly, it isn’t actually hurting our business.
For example refactoring a legacy software product to use clean code patterns and practices might be classed as paying off technical debt – but not if the product is being replaced by a new one and there is no more planned development for it, or if it is being retired because nobody is using it.
Developers will sometimes use this idea of technical debt to try and explain to their managers the need for making changes to existing software that do not directly change its functionality, but instead will make it easier to test and add features and fix bugs in the future. And by easier, I mean quicker and cheaper, and more predictable to estimate.
When they say this, they are proposing paying off some of the technical debt that has accumulated in the software, because they feel that the interest payments are getting too high.
They are saying that the software is painful to work on, fragile and error prone. Development of functional changes on systems with significant technical debt will take longer than it should do, and the changes are more likely to result in bugs. Developers hope that their managers will understand the correlation, and accept the need to make these changes that otherwise may seem to have no obvious value to the business.
As time is money, the metaphor equates Technical Debt to a financial debt, where interest must be paid until the debt is paid off.
However unlike fiscal debt the term “Technical Debt” implies a precision that does not exist. You cannot look at a given software code-base on its own and determine how much technical debt you have. It all depends on how much your software needs to evolve and change in the future.
After all, if you never needed to change one part of the software again, you have zero technical debt in it, however badly designed the code is.
In reality, every time your software is changed, the additional time needed to safely make the changes and test for and fix the resulting bugs is costing you money. It isn’t a strict function of time however, unlike mortgage interest rates, you only pay this interest on areas of the software that you need to change.
Unfortunately, changing software frequently increases the technical debt within it, especially when many different developers have worked on a particular module of code over several years. This means that the areas of the software that you need to change most often, are the areas that end up costing you the most.
We now understand that “Technical Debt is code that is more expensive to maintain than it should be”, and we understand the metaphor of technical debt, and the idea that the extra expense is the interest that you are paying on your technical debt every time you change your software, change after change.
We understand that if you take on Technical Debt, you will continue to pay this interest until you go back and fix the source of the problems, either by refactoring the code, or spending time on a more scalable or maintainable design, or solving whatever the root cause of the problem is.
We can start to see now, why technical debt grows faster in successful software companies. In these companies, there are customers using the software products, and the focus is on adding features that customers are asking for, features that open up new opportunities for the business, or fixing urgent issues that customers are complaining about. This focus is one of the reasons the company is successful. It is also the reason that they attract technical debt.
The things that customers care about, are the things that are visible to product managers, and therefore are given priority.
Technical debt can seem invisible, from the outside at least, which means it often remains hidden in a software application for years, as the important work necessary to pay it down is de-prioritised in favour of the urgent work.
As we saw earlier, if this continues unaddressed, the software will eventually become so unmaintainable that it will seriously hurt your company, and starting to fix these issues when you have millions of lines of code on your hands is obviously more difficult.
Although technical debt is not easily visible, the symptoms of technical debt are all too visible in the impacts it has on your entire software business, and they will continue to increase in severity over time.
If you’re interested in learning more about Technical Debt, head over to our courses page and Become a Technical Debt Detective!
Chaos on Toast Ltd