Why can't we forgive technical debt?
One way in which the debt metaphor breaks down is that technical debt cannot be forgiven.
I have previously shared my belief that Ward Cunningham's debt metaphor should be treated as more than just a metaphor. That's because I believe that the debt metaphor describes a particular phenomenon or situation that programmers encounter in their daily practices. In this article I will touch on one way in which the metaphor of debt does not match the structure of the situation that Cunningham described.
So, what is the structure of debt or technical debt as it has come to be known? One of the earliest phrasings of the debt metaphor goes like this:
Shipping first time code is like going into debt. A little debt speeds development so long as it is paid back promptly with a rewrite.
Cunningham described debt as inconsistencies in the program that show up when local, isolated improvements to the program are made during incremental development. To this problem, Cunningham proposed a particular solution. Technical debt is “paid back” by a process he called consolidation. Paying back debt requires refactoring programs such that debt inducing improvements are made across the entire program, or as Cunningham put it “reorganizing [the program] to reflect your understanding.”
But paying back debt is not the only way to get out of financial debt. For a number of reasons, creditors, the owners or holders of debt, can choose to write off a borrower's debt, stopping any interest payments and bringing the value of the debt down to $0. For example, during the COVID-19 pandemic the US government deployed a number of programs for debt forgiveness, such as, PPP loan forgiveness for businesses and the student loan moratorium and debt relief for college students. Debt forgiveness has also been practiced on a wider scale in the past in different regions of the world.
Can we do the same type of debt reset in our software systems? I want to convince you, the reader, that technical debt cannot be forgiven. Let's look at two thought experiments to demonstrate that we cannot replicate debt forgiveness for technical debt - eliminating debt and eliminating developers.
Deleting the code
The most obvious option we can try for forgiving debt would be to delete all of it, that is, deleting all the code exhibiting debt. But this leaves us worse off than we started, as we no longer have any functional code to meet our business outcomes. Restoring this functionality would require us to replace the code, and this is exactly the effort we were trying to avoid. If we rewrite the code in a way that ameliorates the debt, then we have actually paid off some if not all of the debt. If instead we just restore the code that we used before, we would have failed to address any of the debt.
But this outcome makes sense. If the costs of technical debt are really felt by practitioners, then we can’t write it off in one key stroke. If deleting our code does not lead to debt forgiveness, what else can we try?
Forgetting technical debt
Another phenomenon can help point another way forward. It happens that even your experienced developers may sometimes forget that debt exists in certain corners of the codebase. Thus, another option for forgiving technical debt could be for the development team to forget that they even had it. However, the only way to ensure that all of the debt is forgotten would be to ensure that anyone with a proper understanding of the codebase could no longer work on it. Thus, forgiving by forgetting technical debt would require us to let go of the developers on your team who are most experienced with the system.
Not only is it a bad idea to get rid of your most experienced staff, but this will prove to be only a temporary solution. Once the new developers have sufficient experience with the system, they will begin to uncover the original technical debt once again. As these novices grow into experts they will eventually notice that the debt in the system is not zero.
Why the metaphor fails
The reason the metaphor fails in both these admittedly extreme cases is that there is no separate party that takes the role of creditor in the situation of technical debt. In the debt metaphor we owe a debt to ourselves, we are both the borrower and the creditor. And the interest payments that we worry about paying are not assets we hand over to others but the additional time and effort that we incur whenever we attempt to manage our debt loaded systems.