Managing Technical Debt

Debt seems to be on every-one’s mind these days.  You can’t open a newspaper anywhere in the world without seeing some article about some country’s national debt.  As we all know, countries aren’t the only entities that have debt.  Most households have some level of debt, whether it is a mortgage, student loans, or some level of credit card debt.  There are many different aspects to this debt, but the one thing that seems constant is the idea that with debt comes interest.  The longer you wait to pay it off, the more expensive it will be.

Think of it this way.  When we want to purchase something, we have a choice.  We can pay with money on hand, or we borrow money from our future earnings to pay for it.  In the same way, whenever we work on code, we are either paying for it with “productivity” now, or we can borrow from future productivity.  Both today and tomorrow’s cost money.  The difference is, since we know there is a cost to changing something later in a system, we need to recognize the cost is higher to wait and fix it later.

So how do we work with this and not end up in bankruptcy?  Many of the activities that we have come to associate with agile development will help to get us there.  Here are some thoughts that I like to keep in mind:

Recognize Debt for What It Is

Since we are stating that debt is sometimes necessary, let us at least recognize which kind of debt it is.  If the debt is because we are making a trade-off due to time constraints, we need to see this as a debt that must be paid off soon, like a high interest credit card.  We have accepted a design flaw, or perhaps a defect, in order to get the story out, or the feature complete, in time for a release.   This is not ideal, but sometimes necessary.  On the other hand, sometimes we are going to incur more long term debt.  Debt can be an investment.  Perhaps we are looking at a major change, like moving to a cloud based environment, or a larger technology.  Using the principals of “Do the Simplest Thing That Could Possibly Work” we might use a model that doesn’t take full advantage off the new technology, but gets us started.  It works, so there is no pressing reason to go deeper, or to prematurely optimize, at this time.  We will want to pay this debt off also, but we can do it on our own time, and the cost will be lower.

Keep the Interest Rate Low

We have recognized that we are choosing to incur an increase in the total cost by waiting on a particular feature or issue.  Now we need to make sure that the cost is as small as possible.  There are many mechanisms to do this.  One of the most helpful is to have a large and strong body of automated unit and acceptance tests.  This will be especially useful in ensuring that any design debt is kept to as low a cost as possible.  Limiting our Work In Progress is another excellent way to keep the costs down.  High quality code comes from folks who are not scrambling to get as much done as possible.  Teams that can concentrate on getting the highest quality out there will be better suited toward keeping the cost of change down.

Consider a Payment Plan

Borrowing once again from the extended metaphor, consider creating a debt repayment plan.  Just as we have all learned about personal debt, the best approach is to make the largest payments you can afford against the debt with the highest interest rate.  You still need to make payments against any other debt in order to maintain good standing, but the bulk of your effort goes to paying off the most expensive items.  While agile and lean make this much easier to manage, you can do this no matter what methodology you are using.  When you are prioritizing your stories/features/whatever, also prioritize your defects or other technical debt related items.  Then, whatever mechanism you are using for determining the capacity for the upcoming work, allocate a certain percentage toward paying off debt.  This percentage should be large enough to make a difference, but not so large as to cause no new features or added business value.

As far as the “minimum payments” for the lower cost items, that is where refactoring comes into play.  By continuously improving our design without changing behavior, we are incrementally paying down design debt.  Also consider spending some time inserting new tests in legacy code.  We tend to find “hidden costs” inside the legacy code, so creating unit tests around it will help us to pay those off as well.

Don’t Beat Yourself Up

Lastly, while we will always resolve to take on as little new debt as possible, there is nothing to be gained from beating yourself up for debt you already have.  Take a deep breath, create your payment plan, and keep working on it.  Second guessing is painful and a waste of time.  We would be better off spending that time creating great software.

This entry was posted in Agile Development, Agile Software, Agile Teams, Agile Testing, Agile Tools, Test Driven Development. Bookmark the permalink.

3 Responses to Managing Technical Debt

  1. Tosi says:

    Nice explanation as always Steve. I’ve been kicking around some ideas regarding technical debt – mostly concerned that I have seen it become another shield behind which developers could hide. I like it as a vehicle of communication. Far too often I have seen technical debt become a term used to hide the real issues. Similar to mandates from senior execs around unit testing as a solution to poor quality, I’ve seen technical debt used as the reason why developers have risky-to-change software instead of finding out and addressing why they are creating the software in such a manner in the first place.

    What are your thoughts around debt? Is all technical debt the same?

    With a credit card, if I throw away the credit card, my debt remains. But if I throw away my code… ;)

    Tosi

  2. Pingback: links for 2011-08-19 | Michael Ong | On9 Systems

  3. Pingback: It's a .NET Life - TDD–revisited: (Dallas Tech Fest 2011)

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>