I don’t care how brilliant a developer you are, every piece of code you will ever write will add to technical debt. Yes it will, and it will irritate you to no end.
Technical debt is one topic that instantly sparks debate and ignites controversy. I see the talk of technical debt crop up at work (even though we are still in the earliest stages of the project and haven’t accumulated much), and I see the need to manage technical debt in the code I write myself (even if my projects relatively small in size).
I believe what makes technical debt a development pain point is the fact that there are literally endless ways to continue to improve, optimize, refactor, enhance and generally better the code. Since most capable developers are perfectionists, these opportunities for improvement are a persistent and nagging temptation. It’s an issue that can affect productivity, team morale, and that has direct implications for the business value you are trying to extract from your team’s work.
Given the importance of the topic, I thought I’d share my own perspective and experience managing technical debt in a constructive and healthy way that still makes business sense. If you are lazy, you can skip to the “definite DO’s” at the end of this article.
Technical debt is a rabbit hole that goes deep, really deep…
Psychologically, it’s just tempting to.. wait, wtf?.. did I just call my callback function ‘callback’. Hold on, let me fix that. Oh crap, I am duplicating this chunk of code all over the place, those bits better go in a separate module. And off I go down the rabbit hole…
This is a common pattern. It’s a lot like snacking — before you know it, you’ve eaten the whole bag of chips with nothing much to show for it except effectively managing your urge to snack. You’ve certainly scratched your itch to organize and streamline things, but the program still does what it did before. At the end of the day, a customer is unlikely to see an appreciable difference in features or performance as a result of this work.
They say work always fills the time allotted. Work on technical debt will fill the time just as well, but unchecked it will fill it with things a product manager would never want. Attempts to pay down technical debt without a clearly defined goal, say to refactor a particular piece of code, are usually a recipe for disaster. When it comes to technical debt, a blank check to roam wild will always be cashed for a sum you, as a product manager, would not be prepared to pay.
Technical debt is like a mound of sand with a few grains of gold
Chances are you will never have the time to get to every single grain, but there is definitely a chance that somewhere along the way you’ll stumble into something that rewards you for the effort.
From product management perspective it’s easy to dismiss technical debt as something that can be safely written down at some point in the distant future when you decide to go in a different direction and scrap the whole product or, and let’s be pragmatic here, when customers don’t line up for it down the block like it’s the next iPhone.
It may make engineering happy, but happy engineers do not a happy product manager make (it may be necessary but it’s not sufficient). After all, you are the voice of the customer, and the customer will never ask for consistent naming or decoupled, well-define modules, or a new build system. Why should you care is the question? What’s in it for you when you could be building out the next feature instead?
Every once in a while a miracle happens. Someone stumbles across a radically better way of doing things that brings very tangible customer value. It has happened to me a couple of times (e.g. when refactoring a module lead to an improved algorithm that dramatically changed the scalability of the entire system), and it changed my whole perspective on the value of paying down technical debt.
I went from seeing technical debt as something that was eliminated solely to satisfy the engineering’s drive to perfection to something that is like a high risk/high reward investment in your product. You invest time and effort in exchange for a rare but handsome windfall.
Paying down technical debt is a strategic activity
You are unlikely to get an immediate return for tackling technical debt, but it’s not a lottery stacked entirely against you. In fact, paying down technical debt can remove cruft that papers over serious software flaws, and these initial urges to fix something mundane often cascade into improving something that is very fundamental and important. Improvements in the code often drive improvements in the product.
Intentional technical debt is all about developers making a conscious decision to optimize for the present instead of for the future. Paying down the technical debt is the opposite — it’s about taking the time to optimize for the future. And when you frame it this way, it somehow ceases to be controversial. Compare that with product managers who put on their strategic hats to do market analysis and 3-year product roadmap or the same product managers rushing to answer customer emails. You couldn’t imagine one activity without the other.
In other words, if you do not make room for strategic work (either on engineering or product management side), your product is probably doomed. But how much room to make? Although I ‘d normally shy away from giving absolutely numbers, 20% strategic/80% tactical split on software development has worked for me. If a product is more mature, I’d say that the ratio of strategic effort (including the effort to pay down technical debt) can go up. If a product is still in pre-launch phase, I’d say 5-10% would be reasonable too.
Your mileage may vary, but the definite do’s are:
- Draw a box around the work at goes into paying down technical debt. Define exactly what gets addressed as part of the effort and go no further.
- Accept and make peace with the fact that you will never be done, but invest in paying down technical debt for those rare fortuitous discoveries that bring customer value.
- Find an avenue for engineering to escape the tactical grind to pay down the debt. This is part of your long term product strategy, and it’s not only good for the product, it’s good for the team.