But that’s not really what “debt” means.
Most of us think about debt from the perspective of personal finance – that is, largely as a convenient way to buy things and pay for them later. Or perhaps from a debtor’s prison perspective: something to be avoided, or certainly paid off as quickly as possible. But when engineers raise the topic of technical debt, they’re often communicating with business owners, who often have degrees in business or economics. To such a business person, this is simply not what “debt” means. When an engineer talks about technical debt to scare managers into worrying about operations (“We have a ton of technical debt, we need to fix it!”), it kinda sounds to sophisticated business people like… well, like what those same business people sound like when they try to justify new technologies to technologists: “I want you to blockchain the virtual. Right away. Because it seems like we don’t have enough AI, yet.”
A business leader may be thinking about things very differently. Many may think about debt in terms of leverage. Well-structured debt is a benefit; it provides extra money we can use today. So if you talk to an options trader about having a ton of technical debt, their reaction is likely to be, “That’s fantastic! how do we get more?”
It’s not about debt.
The term invites us to focus on the wrong part of the problem. The casual interpretation of debt suggests that problems accrue because we are borrowing time from the future and being lazy about paying off our debts, and that is inaccurate and unfair. In fact what we’re doing is making intentional, mindful decisions about opportunity cost.
It’s not debt; it’s future value. Those are related but different things.
I’ve often said that “every keystroke a developer makes is a business decision.” We are, every day, in almost everything we do, continuously trading off opportunity cost: should I do a thing now, or wait and do it later so we can do something else now? When I decide it’s not worth adding a comment to piece of code, I’m fundamentally trading off the value of investing the time right now to clarify my intent against the time a future developer (usually me) needs to spend figuring out what the hell that code is doing. When I decide not to introduce a new abstraction to make the code more flexible, I’m trading off the value of investing time right now so it will be easier to do something else later. These are all opportunity cost decisions.
Sometimes… you just do it
- I always clean as I go. It’s like housework. You never really need to vacuum, because if you leave it until you actually need to vacuum, your carpet is [elided].
- If I have trouble understanding some code I need to work on, I’ll often refactor to help clarify. This requires good unit tests, but of course if you don’t have good unit tests what you’re doing isn’t refactoring. So I’ll add unit tests first, which also helps explain the code (“wait, it does what now?” is sometimes a very useful test result). Then if needed I’ll refactor to improve comprehensibility.
Sometimes… you gotta think
But when times are hard and things are bad, sometimes you need to worry about the cost/benefit of an investment. When that happens, the considerations change. Such investments require more justification, but the underlying trade-off is pretty straightforward. As my current manager says, “If it saves us more time than it costs us, we make the investment. It’s just that simple.” Quantifying this isn’t easy, but that’s what we’re trading off. Large changes, whether it be factoring the code, re-architecting your system, or just replacing it outright, need real forethought about the return on the investment. The rubric is not “debt” – it’s simply trying to decide whether the investment will pay off in the long term or not.
We cannot get that completely right – there is always risk that we’ve overestimated the return, or that we technology simply won’t be around long enough to justify the investment – but that is the decision we’re trying to make. Once again, it’s not about debt; it’s about opportunity cost and return on investment.
So, many technical leaders at Amazon lean away from the term. It’s not that the concept is wrong; it’s that it puts all change into a single basket. The question is not whether the code has problems; it’s code, it has problems. The question is whether the value we get in return for fixing it justifies the investment in fixing it.
It’s not technical debt. It’s technical opportunity cost.