Faster Software Development with (Smart) Technical Debt
- “technical debt” noun.
- the sum of costs owed to one’s computational progeny for past transgressions
against their design and future well-being
If you’re like me or anyone who’s spent enough time in software engineering, when you hear the phrase “technical debt,” it conjures bad associations and worse memories. Because by the time most people actually talk about it, it’s almost always a bad thing. But there is a case for incurring technical debt proactively, on purpose, and very judiciously.
Did you really just advertise that you’re going to intentionally build technical debt into your projects?
Yeah, I kind of just did. The important thing is for everyone to know about it first and make an informed decision. There aren’t many products in this world whose value is measured by the beauty of their code. At Revelry, we’re compulsive about shipping good code because we love it, but we’re obsessive about always shipping because it is the most important guarantor for success.
Let’s talk about technical debt like… well, debt.
A lot of technical debt in the software world arises from sheer desperation. This is the pay day loan of technical debt. If you need it, you’re already broke. The more you take out, the worse it gets. If your project is already in this situation, you can stop reading here. You’re in deep trouble, and nothing I’m talking about is going to change that.
Back in the monetary world, we have things that are traditionally considered “good” debt. Student loans to enable you to make a more lucrative living. Home loans to stabilize your housing expenses and own property that will (hopefully) appreciate in value.
“Good” technical debt is the prototype that gets your startup funded. It’s the bare minimum viable product to validate your idea (which you need to do, by the way.) It’s the new product feature that increases revenue, or the optimization that drives down costs.
These are all valid reasons to put productivity ahead of purity, as long as you can afford to pay back the loan, or better yet, it gives you something that will appreciate in value.
So now that you’ve decided that you might have a good case for taking out some technical debt, here are some absolute musts for doing it responsibly.
A throwaway prototype is a throwaway prototype.
Every once in a blue moon you might have set out to make a crappy prototype and accidentally nailed it. But most of the time it’s just as bad as it set out to be. Don’t build on it. Throw it away. Technical debt should not be the foundation of your product.
Get consensus first.
I touched on this already, but don’t go rogue and just do it without talking to
anyone. This is a serious economic decision with potentially lasting impacts.
You shouldn’t be deciding on your own what is or is not a good debt for the
product owner to take on.
Contain the disease.
If you’re going to write ugly hacks, make sure they’re modular, self-contained ugly hacks. When you rewrite it, will it still fit gracefully into the system around it? Is its interface to the rest of the system what you would expect from
a good solution, or is it a nasty symptom of the hacks within? Don’t let the disease spread into the rest of the system.
Comment the code like your life depends on it.
As a general rule, comment quality is far more important than quantity. A code file covered in comments
that state the obvious almost might as well not have comments at all. In the case of intentional hackery, your code demands a large quantity of high quality comments. If you’re going to knowingly write some hacky code, you have to provide the necessary information to make it possible to fix.
Make sure it goes through serious scrutiny.
You do code reviews, right? Let’s assume you do. This isn’t the place for “Wouldn’t it be more elegant if…?” discussions that don’t get the feature shipped. The decision has already been made because you’re responsible, and everyone agreed this was the best way to meet your goals. But colleagues do need to be notified that they’re looking at a quick-and-dirty hack so that they can judge whether or not you’ve lived up to the responsibilities that come with the territory.
Have a plan for paying back the debt.
How and when to pay it back is a product of just how bad the problem really is, how well you managed to contain the disease in practice, and how often this ugly hack requires changes. Some nasty hacks can live a long healthy life before they ever require intervention. They might not have really even been technical debt after all.
Let’s go back to another flimsy monetary debt analogy. You’ve got debts that cost you 2% in interest, and the capital is reinvested at a 4% return. So you’re actually making money off your debts. When do you pay them back? When the interest rises too high, the returns fall too low, or the investment becomes too risky.
Technical debt is like that, just more abstract. Set some conditions upon which you will pay it down. The first time the hacky part of the code needs different behavior? When it begins to take 30% longer to modify it should? When it generates more than 5 bugs per quarter? Every organization and project may have a different answer. But make a plan and be vigilant about it. Good debt doesn’t stay good forever.
It’s more a culture than a process.
Processes should be light, flexible, and get out of the way. If you were to build a rigid process around everything I just talked about, you would waste a lot of people’s time and defeat the purpose. (Besides, inventing a process which combines gross code with slow delivery sounds pretty unoriginal.)
At Revelry, we’ve got our share of process, but education and trust are what develop a culture of independence that enables our people to be effective. These are some of our core values. Ultimately, conscious technical debt is an act of pragmatism. Done with care and purpose, it can be a valuable tool.