The uphill battle of prioritising technical debt

Wanna know how you can prioritise technical debt and reduce it? There are no three easy steps solutions to do so. It’s more complicated and messier than that. You need to translate technical debt into business impact. By framing technical debt as cost we have an easily understandable metric we can use to rally for support. After all, if technical debt does not hurt the business in any way, why should anyone care?

Technical debt hurts the bottom line

Don’t fall into the trap of measuring technical debt only in technical terms. Calculating your maintainability index certainly has its merit. But it won’t put your technical debt on anyone’s roadmap. If you tell a product manager how insanely high your cyclomatic complexity is the only reasonable answer is: So what?

What you really want to show is how bad your technical debt is for your business. That means you want to frame your technical debt as a monetary value. Start measuring the impact on developer productivity, cost of interrupted service or estimating impact of black swan events like security breaches. Here is a more extensive article about how you can measure technical debt.

Technical debt is not technical

Stop looking at technical debt in isolation. A fundamental problem of not erasing technical debt is that it has to compete against feature requests. Such feature requests often have a clear business case and are much more predictable. They pay into your shiny new company strategy directly and look good on your CV. Yes, the cards are stacked against you.

Add to this the uncertainty and high risk for any individual or team tackling the technical debt and to understand why it is so hard to prioritise technical debt. Especially global technical debt comes with another layer of difficulty. Such debt is not owned by a single team and it does not affect a single feature. How technical debt comes to be and grow is a good example of the tragedy of the commons. So let’s find a way to counteract all those problems.

A continuous budget for technical debt

Let’s just be adults about it. We’ve seen that technical debt slows your team down. Instead of fighting a constant prioritisation battle we can simply set aside a certain amount of time for working on our technical debt, we’ll call this the 80/20 approach. 20% of your team’s effort is consistently spent on technical debt.

This approach brings with it a few advantages:

  • You can continuously work on technical debt
  • The prioritisation process stays simple. You can prioritise technical debt and product features separately.

But unfortunately it falls short in some aspects as well:

  • If you only have a day in a week to work on technical debt, you will focus on small tasks leaving the bigger, more severe issues aside.
  • You’re multi-tasking which means both the feature work and technical debt take longer to get done. Besides that you’re wasting time switching context.
  • We focus on how much time we spend on technical debt, not on the impact and outcomes of our efforts
  • When the pressure is on to meet deadlines the 20% of your technical debt time is hard to defend and justify. What starts as a one-off exception can quickly turn into a 90/10 and eventually a 100/0 split.

RICE is not just for cooking

Let’s see if we can do better than assigning a continuous budget for technical debt. With the RICE prioritisation technique we can try to frame our technical debt as business opportunity.

You assess the Reach and Impact of your opportunities, add your level of confidence and the expected effort. With those four variables you can then calculate a number for each opportunity, your RICE score. The higher the more valuable the opportunity.

Prioritising features and technical debt with RICE

Let’s try to compare a feature against technical debt with RICE. The feature we want to build is a new API endpoint. The technical debt we want to repay is replacing our API gateway.

The new API endpoint can reach about 50.000 of our customers and the endpoint has a medium impact (you can use any scale, for example 1 – 5) on their business, it’s a “nice to have”, so we’ll score it with a 2. We’re relatively confident (80%) that our numbers are accurate because we did the customer research and analysed feature requests. It’d take one team roughly 3 weeks from concept to production.

Now we calculate Reach * Impact * Confidence / Effort which comes out at the random number of 32.000. It’s over 9.000 which is good I guess. Let’s do the same for our technical debt.

The API gateway on the other hand is a central piece of our architecture, affecting every single customer. Let’s say that number is 350.000. The impact on each one of them is arguably smaller, because there would only be the performance improvement here and there and one of the other fixed edge case. So we’ll score it with a 1. It’s technical debt so we can’t be sure that the new gateway will deliver on all its promises. So we’ll only give it a 60% confidence score. Unfortunately it’s also not the simplest so you need two teams for roughly 4 weeks, 8 weeks in total. Let’s do the math: 350.000 * 1 * 0.6 / 6 equals 26.250. That proves how our technical debt is not as valuable as our shiny new endpoint. But does it really?

Leave the RICE for the kitchen, not the codebase

RICE is great for giving you a framework to look at certain data points and making rational decisions. However, in this case it has a few shortcomings:

  • It’s customer centric. We’ve assumed that technical debt will provide customer value and that this is the only important dimension. But maybe the biggest value in fixing technical debt lies in gained efficiency and reduced cost through developer productivity. Unfortunately there’s no easy way to measure those different forms of value against each other. Back to square one.
  • While you can define the reach and impact with reasonable effort your confidence and efforts are really just opinionated estimations. And your estimates tend to be pretty bad.

Okay, so far we have discovered to ways of how we can not prioritise technical debt. Let’s give it one more try.

Show me the money

Let’s try expressing our technical debt in terms which really matter to the business: money. Let’s try to answer how much technical debt costs us.

Technical debt is often not directly tied to a single feature. The most painful technical debt is systemic, affecting development across the organisation. It makes every feature touching it slower and more expensive. This costs us in three different ways: Developer productivity, delayed feature releases and infrastructure cost.

Measuring developer productivity

The simplest way to measure the impact on developer productivity is marking every interaction with the technical debt. Over a longer timeframe you can then do a simple statistical analysis. How long does a feature or pull request take on average? How much slower from first commit to production is your feature when it has to interact with the technical debt?

While this is only showing correlation and not causation, it still gives us some comprehensible data. Let’s say that the average developer works 20 hours for an average pull request. Features touching the technical debt take 30% longer, so about 6 hours. In a month your whole organisation creates 15 of such pull requests. Your average engineer costs you $70 per hour. 6 hours * 15 pull requests * $70 * 12 months makes over $75.000. That’s almost a full engineering year just spent on this. But consider that this is only one single piece of technical debt. Also, it’s only one piece of the puzzle.

Fixing technical debt boosts efficiency

The even bigger implication is that every feature takes 30% longer to build. That doesn’t just cost you in terms of engineering salary. It costs you time that your feature could already earn you money. In product management this is called cost of delay. A product doesn’t exist in a vacuum. It has a lifecycle. While you’re still building your competitors are snatching up your customers. Here you can read more about the cost of delay but for now we just focus on the numbers. Because of the technical debt and the product-lifecycle we can not generate as much revenue from the new features we ship.

Let’s say on average a feature helps our sales team to onboard 20 new customers, netting us $500 each per month, $10.000 in total per feature. If your feature is one month late you lose $10.000 in profits. Let’s say we ship 3 features each month, one of them a month delayed because of technical debt. That’s $10.000 revenue lost each month, or $120.000 a year.

If you add up the lost developer productivity and the cost of delay we can estimate our technical debt costs us almost $200.000 per year. Now that gives us a fighting chance against all those features. In fact it changes the narrative from working on feature or working on technical debt to:

If you want to ship features faster, tackle technical debt.

Prioritising technical debt is cost reduction

Developer productivity and cost of delay are just two examples how you can put technical debt into a financial context. In your organisation it might be infrastructure cost or developer churn or customer churn and dissatisfaction.

Translate technical debt into the language of business to put technical debt on your roadmap. Try to find an angle where you can reasonably estimate its impact and cost. If you can highlight how much revenue your organisation is leaving on the street it makes it much easier to prioritise technical debt.