Thursday, April 16, 2009

Technical Debt: Paying it Off

Let's face it. This isn't going to be easy. Paying off your technical debt is like paying off your credit card debt. You do the work, make the payments, and the only reward is watching your balance go down. You don't actually get any snazzy new features marketing cares about. This means it's going to be a rough sell politically. Your only hope is the promise of future reward: with less technical debt you'll be able to produce features better faster more reliably... you just have to spend some time paying down your debt to get there.

So, how do we start paying it off?

Be a Salesman
In general you can pick and choose your approaches to paying off technical debt. Do some things that work for you, and don't do things that aren't helpful in your particular case. Selling the idea of paying down technical debt, though, is pretty much always going to be necessary. Unfortunately, as an engineering team you don't usually get to pick everything you do. You're captive to the needs of the company as a whole. Marketing needs things, sales needs things, support needs things, engineering needs things. If "paying back technical debt" is going to be one of those things, you need to make sure it gets on the list of tasks and stays high, even in the face of all the other important things. Congratulations, you're now a sales guy.

So, what arguments can you make to help others see the importance of paying down this debt?
  • We need to polish some features. Let's face it, dev has cut a few corners to meet dates and features. Bring up specific and recent examples of those cuts, and emphasize what your users can't do or your marketers can't say. For example, we did a feature that was basically a script that gathered information off each system and emailed it back to support. It's incredibly useful, but it wasn't really done. It wouldn't automatically move to another node if the node it was running on failed; it couldn't detect if it was running on two separate nodes (and would send back data twice), etc. Finishing that off will make support's life a lot easier, and prevent us from having to call up clients and get on the system to restart the thing. The point to emphasize here is that cleaning up technical debt improves the product directly. This same basic argument applies when you're trying to fix bugs.
  • It will make implementing future features faster. Right now implementing features requires you to work around necessary refactorings, etc. If you can do those, it will make it faster - and you need to specify to some extent how much faster - to do certain features in the future. Be sure you also note how often you have to do these things. You're trying to show that you get a net benefit from doing this. 
  • We can test more efficiently, which will shorten our release cycles. When code is cleaner there is generally less test overhead. Running each test may or may not be faster, but you'll spend less time chasing down bugs that appear only in some places and not others. In clean code, bugs are more likely to appear in all code paths, rather than being long dependent sequences of events. The net effect will be fewer bugs found, fewer bugs found late in the process, and fewer bugs found after release.
  • It will make our code more attractive to a partner/customer/buyer. This argument may not apply in your situation, but if you're a startup with an exit strategy, or if you want to raise a round of funding, or if you sign deals with partners or clients that include source code sharing, then it starts to matter.There are popular websites dedicated to laughing at bad code; do you really want your company to show up? Clean code inspires confidence, even before you run it, and that's the kind of confidence you want to instill in someone doing due diligence.

As with all convincing, specificity is your friend. Specificity using examples your audience cares about is even better. With support, using a support-related example showing simplicity and reliability will help. With marketing, talking about the great new features will help, etc.

Just Pick Already
A really good way to avoid paying off technical debt is to spend a lot of time figuring out what to do. Don't do this. Yes, analysis is important, but it must be timeboxed. Spend no more than 2-3 hours figuring out what technical debt to pay off first. Then go do it. Launder, rinse, repeat. The trick is to not get bogged down in analysis.

Also make sure you pick something that you can accomplish. The trick, as with much development work, is to pick things small enough you can do them before you get interrupted. Think "refactor file system management code", not "refactor entire system management framework".

Balance the Customers
Now that you've sold your "paying off technical debt", you need to show improvements to everyone you've convinced. So when you've done a refactoring to make dev/QA happier, follow up with some polish on a feature that didn't quite get done. Your goal here is to be able to show positive effects to multiple stakeholders - marketing, sales, support, dev, etc.

Fix Recent Pain
You're never going to get all the time you want to fix all the technical debt; this is not a fast process. You need to prioritize fixing things that have hurt you recently. So when you're picking something, think about what hurt you recently. It's fresh in your mind and it's fresh in your stakeholder's mind, Any change you make to fix recent pain will help you keep going because the benefit is easy to see.

Whiteboard of Ideas
I keep a whiteboard up in a common area in the office. On this white board anyone can put technical debt as they see it. Got a story and didn't have time to polish the edges? Put it up. Had a problem at a customer site and needed manageability changes? Put it up.

Now, this is a dangerous thing, and you have to police it. This is not a place to put all enhancement ideas. And nothing on here can be vague. Rather, this is your list of accomplishable technical debt to pay off. Think, "refactor Performance tests to use standard base test class", not "make product 5%". For this reason, I generally filter ideas through a small subset of people (team leads) - only if they agree it's actually technical debt do we put it up.

Measure It
You've promised improvements. You've said that spending time reducing technical debt will reduce the number and severity of bugs found. You've said it will result in fewer calls from customers with issues. You need to show it as well, or you won't be as believable next time. So before you actually start work, you need to figure out how you're measuring your results.

Do a bug find rate before and 6 weeks after you've done some work to see if it's really going down. Start mapping your customer call rate before you start work; in three months see if it's gone down. Check your estimation accuracy before and after refactoring - look to see both shorter implementations and more importantly, more accurate estimates. Numbers speak volumes.

What I'm Not Going to Tell You
I'm not here to tell you how to actually go about refactoring, or finishing features, or whatever. Use your development process for that. This is really about recognizing, identifying, and finding ways to pay off your technical debt.

I'm also not going to tell you this will be quick or easy. This is something you're going to be doing for the life of the product - a long time, I hope! Plan for this to be part of a reliable, sustainable product creation process (notice I didn't say development process - this involves everyone).

Technical debt is a big scary thing, but it is conquerable. Put your mind to it, and keep it in the forefront, and your technical debt can be paid down and kept to manageable levels.


Other posts in this series:
Technical Debt: What Is It?
Technical Debt: Warning Signs

No comments:

Post a Comment