The Value in Accruing Technical Debt
Steve Freeman wrote an excellent article on “Bad Code”:
Call options are a better model than debt for cruddy code (without tests) because they capture the unpredictability of what we do. If I slap in an a feature without cleaning up then I get the benefit immediately, I collect the premium. If I never see that code again, then I’m ahead and, in retrospect, it would have been foolish to have spent time cleaning it up.
The analogy is especially poignant because we’ve all been in the situation where our time is spent fixing expensive bugs in old code. He is exactly right. Bad code is like a call option: an infinitely risky choice.
###Why would you ever sell a call option?
So then, why do some people sell call options? Or to carry over the analogy, when would you write bad code?
Selling an option is like entering into a contract with someone that dictates they can buy two super bowl tickets from you in 2 years for $3000 (tickets often sell for around $2000 each). If you can get the tickets for less than $1500 then you’ll make a profit. If however, the tickets skyrocket to $5000 a piece when they decide to buy you would lose $7000.
You sell a call option when you know (or expect) the value of the product will go down. 1 Meaning you SELL the contract now for a price because you believe you can BUY the product for a lower price at a later time. (You sell Super Bowl ticket contract for $3000 when you are very confident you will be able to get them for less than $1500 a piece.)
We pay for our code with time and the lost opportunity of additional features. If you have to spend time fixing buggy code you can’t add new features.
If you are writing code that is crappy, it means you think you’ll have more (cheaper) time later to write better code. You are selling your product now because you are confident you won’t be spending time on new features later. Is that true? Or are you making a bad judgement call?
Are you unintentionally betting against the future of your product?
Some contractors may be working on a one-off product. In that case, it doesn’t make sense for them to invest heavily in well written code. They sell their unwritten work for a set price, and then build it for as little as possible.
However, if it’s a product for which you have long term plans, and future features to add, bad code is the wrong side of the table. When we bring on users then our time will be more expensive, not less expensive. When we our product has paying customers we’ll have stricter requirements on how we spend our time, not looser requirements. If you believe in the future of the product, you shouldn’t write bad code.
###There is, however, a place for technical debt.
Debt as a tool is simple. Imagine you could buy an app for $20,000 that makes $10,000 a year. Would you do it? Maybe not for cash. But what if you could buy it with a bank loan? If the terms of the loan allowed you to pay off the loan in 5 years, you could grow the business and get a reasonable return on a very low up-front cost. If you believe that the business will grow, you’re willing to take on the $20,000 risk with the expectation that paying off that debt will be feasible.
You incur debt when you expect the value of what you’re buying to go up. Meaning you BUY the contract now because you believe you can SELL the product for a higher price later (over time). It’s important to note that the technical debt I’m referring to isn’t going back and rewriting old code. You may have a little bit of refactoring later, but true debt is something you don’t pay for now.
It’s entirely possible to fake out or leave features unfinished without writing bad code. For example, management may want to include “delete user” in the minimum viable product. You may buy that feature with debt (not actually paying for it) by including an email concierge service to delete a user. (The app enables the user to send an email requesting to remove a user and you manually delete the user rather than writing code to automate it). You are selling the feature for a premium because you didn’t pay for it yet, and you can write code that accomplishes the feature later using the profit you captured in the period the feature was manual (i.e. hiring more developers).
You may look at your product and find features that you can purchase with debt (meaning you don’t actually pay for it today, but offset it to the future). If you believe that in the future your team will grow and you will have a greater ability to spend time on features and performance, you may consider faked or manual solutions that come with very little up-front code cost. Be cautious: too much debt can eventually bankrupt a product. However, when used wisely debt may allow you to move faster than you could otherwise.
Steve Freeman was right, we don’t know the future, so we should be far more careful with the code we write. Bad code is a blank check to be cashed in the future.
However, true “Technical Debt” actually is a valuable tool that developers and product managers can use in order to work around implausible delivery dates2.
I’m aware, and maybe you should be too, that most investors that sell naked call options simultaneously hedge their bets by protecting some of their downside with another call option at a higher price. This may carry over into where you may write better code in another area of the app, or you may hire another developer to go back through and write tests or fix bugs in a second pass. ↩
That’s actually Freeman’s term, not mine. ↩