Introduction to Technical Debt
I first came across the concept of Technical Debt whilst reading a recent copy of the Microsoft Developers Journal called the MSDN Magazine. It struck a chord, as it's a concept that all software developers are familiar with, even if not by name.
In every software system, there are areas of the code that are difficult to change, that strike fear into us when we are required to change them. Those areas of the code that make you think "Oh please no". They are difficult to modify or extend, and thus working in those areas are prone to making the system less stable. They will also generally require a greater degree of regression testing to ensure that you have not inadvertently modified other areas of the system.
Technical Debt may be introduced into the code base by conscious decision (in order to make this deadline, we will deliberately and consciously write something "quick and dirty"). Or Technical Debt may be introduced unconsciously by factors including:
- low skilled developers
- ever changing requirements
- impossible deadlines
- poor project planning
- all of the above
In short, you have acquired Technical Debt. You have taken a shortcut with the code to meet a deadline, and at some point, you are expected to repay the debt, i.e., to refactor the code and remove all the hard coded values, shortcuts, etc. that were introduced to meet the deadline.
It is not necessarily always a bad thing to acquire Technical Debt. If the decision is made consciously to meet a deadline where there is a financial gain to be made, such as if there are penalties for late delivery on a project, or a bonus for meeting the deadline. In such cases, then clearly meeting the deadline takes precedence. What needs to happen next (and unfortunately rarely does) is that the business then allows the development team to repay the debt.
The reality is that the business has already moved onto the next project, and the development team is never allowed the opportunity to repay the Technical Debt. Over time, with successive projects each adding more and more Technical Debt, the code base slowly erodes in quality, and the development team struggles to meet each new deadline. The code base becomes increasingly harder to modify and changes become ever more difficult to make.
Similarities with Financial Debt
The phrase was initially coined by Ward Cunningham, and uses the metaphor of finance. There are certain kinds of debt that are cheap to repay, where the interest rates are low and repayments incur little cost. Then there are those kinds of debt that are difficult to repay as the repayments are high. A credit card would be a good example of the latter, where their high interest rates make them an option that should only be considered as a last resort.
An example of a low interest debt would be hard coding a single value into the code base. This can be easily and quickly refactored at a later date. An example of a high interest debt would be compromising on the underlying design. This would be difficult to repay due to the associated costs (time) involved.
The major downside of Technical Debt is that it has an associated cost. Being difficult to modify will lead to longer development lead times. It will require additional testing, particularly regression testing. All of this extra time and effort involves greater cost.
It also ensures that the software system in which the Technical Debt finds itself will be less likely to be able to respond to customer changes, or fluctuations in demand or functionality. If there is a swing in customer demand or a new market opportunity opens, and the system needs to change to be able to respond to this, it will require far greater resources to make those changes in a software system which has a higher degree of Technical Debt.
I remember whilst working for one particular company, a colleague telling me how he disliked modifying certain areas of the code, as it was like "playing Kerplunk with the code" (think Jenga if you haven't heard of Kerplunk). What he was referring to was that by making changes to the code, the whole lot would collapse.
Repaying Technical Debt
Technical Debt is a simple concept that every software developer both understands and can sympathize with. If left unchecked, it can lead to significant cost implications, so it is worthwhile investigating and taking the time to remove it. There is a strong financial incentive to make the case for removing Technical Debt, and this should be proposed as a project as early as is convenient.
In one company I worked for, we consciously repaid Technical Debt by spending one day each fortnight refactoring areas of the code where we had previously introduced shortcuts to meet a deadline. It is generally accepted that a developer ought to spend around twenty percent of their time repaying Technical Debt. So by rights, one day per week should be the appropriate balance. In reality, this is rarely achieved.
If the business understands nothing else, it understands the concept of cost, particularly where it is detrimental to the business. Therefore, a smart business will invest time in repaying Technical Debt.
After each and every project, the accumulated Technical Debt ought to be repaid so it never gets too high. This needs to be understood by the business, at all levels. Not just by the Development Team. Before the business commits to the next project, they need to repay the Technical Debt they have acquired in the last project.