Welcome to the next week!
I laughed hard right after entering the room. During the call, my friend Arek told someone: “We’ll add it to tech debt.” It was years ago, and I probably heard that term for the first time. I was in my sarcastic heyday and thought it was a good joke. But Arek didn’t make a joke. He was serious about it being in the planning meeting.
Technical debt. Reread it. It even sounds silly.
It's a term that gets tossed around a lot in our industry. We mention it in meetings, bring it up during code reviews, and use it to justify refactoring efforts. I believe that technical debt, as most people understand it, doesn't really exist. It's a convenient label that lets us acknowledge issues without actually addressing them. I’ll try to justify my bold claim in today’s edition.
The Illusion of Technical Debt
We've all been there: tight deadlines, management pressure, and the temptation to cut corners to get something out the door. Ward Cunningham introduced it in 1992 at the OOPSLA conference. He said:
Another, more serious pitfall is the failure to consolidate. Although immature code may work fine and be completely acceptable to the customer, excess quantities will make a program unmasterable, leading to extreme specialization of programmers and finally an inflexible product. 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. Objects make the cost of this transaction tolerable. The danger occurs when the debt is not repaid. Every minute spent on not-quite-right code counts as interest on that debt. Entire engineering organizations can be brought to a stand-still under the debt load of an unconsolidated implementation, object- oriented or otherwise.
The classic idea of technical debt suggests that we can take a shortcut now and "pay it back" later, like borrowing time from the future. But once code is written and shipped, it's part of our reality. There's no magical account where we can deposit future work to settle the debt.
Lannisters always pay their debts, and developers also do, right?
Imagine a team pushing hard to deliver a new feature. To meet the deadline, they skip writing unit tests, promising themselves they'll add them later. The feature ships on time, but the tests never get written as months pass. Is it an issue?
Some can say, “sure: it’s a tech debt”.
But why is it an issue?
Or giving you a hint: when will it become an issue?".
Cutting quality corners will obviously increase the likelihood of bugs and security issues. When we surface them without tests, we’ll have a harder time diagnosing and fixing them.
But if I told you that the team were:
building a proof of concept,
delivering an internal tool supporting the process,
setting up a one-time user reporting tool,
bumping dependencies in the legacy system,
doing the first change since a few years ago to the old system.
Would that change the perspective? Would you still call it a tech debt?
The quality corners could have the same scale, but the consequences would be more or less severe. Tech debt is not an issue by itself; the consequences of our decisions can become an issue.
By labelling the absence of tests as technical debt, we postpone the real issue. We do not acknowledge that we made a trade-off: speed over quality. The term becomes a crutch, allowing us to feel okay about not addressing the underlying problem. It’s an easy excuse.
“I’ll just put this over here, with the rest of the fire”.
I've seen that so many times, and I’m fed up with that narrative.
We know where tech debt lands, in the dark place called the end of the Jira backlog.
Keep reading with a 7-day free trial
Subscribe to Architecture Weekly to keep reading this post and get 7 days of free access to the full post archives.