One of the key themes In the upcoming presidential election is what should we do with the US fiscal debt. Some argue we should stop everything to pay it down right now; others think we should put our resources into improving the economy and then pay it down later when we have more resources (i.e. more GDP).
Technology companies face the same dilemma on a micro-level every day in terms of what is commonly called “technical debt”. When developers write code for a product, they are inevitably writing in assumptions as to which things they will be developing more thoroughly and which they won’t. For example, a developer initially coding an iPad app to track weight loss would likely put in extra code to record and share your weights on an iPad and not nearly as much code to record morning heart rates or sleep patterns or to record weight on another device like an Android device or a website.
The challenge is that your initial assumptions when you code often end up being completely wrong. What you thought was definitely on the roadmap last week, might fall off completely after talking to more users, hearing about a competitor, etc… Likewise, the thing you thought was a tiny feature two weeks ago when you started building it now is considered the core of a huge new platform.
The result is Technical Debt — you end up with oodles of code that are being used for purposes for which it was not initially intended. The code is sub-optimized so you end up taking much longer to build things, usually with more lines of code and more bugs. The longer you wait, the more the TD will cost you valuable time and resources. But fixing it means stopping new features, and spending time rebuilding functionality that already works. It just feels like you are wasting time that could be spent adding new functionality.
Every development product I have ever been involved with has at least some levels of technical debt. So what do you do? When do you pay it down and when do you ignore it?
One engineering philosophy wants to err on fixing all bad code. As soon as you see any poorly written code, stop what you are doing and go in and find a more elegant solution.
At the other end are the people who don’t want to fix the code until it actually breaks and then go in and only clean the part that is broken.
I am somewhere in the middle. While it is great to have super-elegant code everywhere you look, I think it ends up being a waste of time as you’ll be over-optimizing. Sometimes, once the code works you never need to change it, so spending hours refactoring it to make it elegant decreases overall efficiency. At the same time, waiting for the code to break and only fixing the part that needs fixing ends up penny-wise pound foolish. You are spending all your time and money repeatedly repairing an old clunker when it would have been cheaper and faster to just get a new car.
So here’s my philosophy. When considering technical debt, I think about 3 things and make my decision based on them.
1) How will cleaning up the bad code affect the next few sprints in your roadmap? Fixing something now that won’t really help make your next few sprints faster is probably not worth your time. On the other hand, if fixing technical debt will speed up development of functionality you need to build soon, you may be able to get it in for free.
2) What is the frequency of profanities — How often are you cursing the poor code quality? If the curse index is high, it probably will help both productivity and morale to fix it. On the flipside If you don’t hear people complaining about it a lot, it probably is not a huge pain point.
3) How firm is your deadline? Everyone has deadlines, but if your next deadline is an absolute MUST-make (i.e. you are showing it to your largest customer’s CEO on date XX), you may want to just delay the technical debt until missing your deadline is not quite as costly.
So how do you handle technical debt?