Most of us in software have at least a modest understanding of technical debt, but have you ever thought about the entire lifetime cost of technical debt?
In this article we’ll take a look at a fictitious piece of technical debt from inception to resolution.
My goal is to get you thinking about technical debt from a few different angles.
Accepting Technical Debt
Our scenario opens with a company working hard to meet a deadline. There’s a huge financial upside to being feature complete by a demo at a major trade show.
It’s the last sprint before the demo. Things are going well, but the schedule is tight. In stand up, Kayla describes a feature she’s working on and how the degree of complexity is much higher than expected.
Kalya estimates that it will take 8 hours to do the feature properly, but there isn’t enough time left in the sprint. Dwayne offers a suggestion that would let the team meet the critical need in only 3 hours.
After some deliberation, the team decides to go with the short term workaround and creates a backlog item to clean up the feature properly after the deadline.
The team completes the feature as planned, the deadline is met, and the company profits from the team’s decision.
At this point the team has gained 5 hours of productivity (principal on the loan) from taking on the debt.
Early Interest
After the demo occurred, the business made a number of key sales and commitments that were huge achievements for the company. It’s an exciting time for the company and the team is happy to see their work rewarded.
Because of several bugs discovered during the demo as well as some new features needed, the technical debt ticket didn’t make it into the next sprint.
Additionally, during the sprint, Dwayne discovers that due to the workarounds the team took, he now needs to spend an extra hour of development while implementing a new feature. This can be thought of as interest in our financial metaphor.
Let’s pause here and look at this scenario on a waterfall chart. This is a financial chart looking to chart financial transactions over time. It seems only appropriate to represent a financial metaphor such as technical debt using a financial chart, after all.
We read this chart as a left to right story. Here we gained 5 hours of productivity by taking on the debt, but lost 1 hour due to the work, resulting in a net gain of 4 hours of productivity.
Additional Debt
The next sprint, the team includes the task of paying down the technical debt.
However, before Kayla can begin work on it, a pair of urgent bugs come in that need to be added to the sprint. These bugs turn out to be due to the workaround. Each bug takes 3 hours to replicate, write a test for, fix, test, and patch into production.
Additionally, Kayla ran out of time to pay down the debt so it slips to a future sprint.
As a result, our waterfall chart now looks like this:
At this point the team has lost 2 total hours of productivity due to the initial shortcut – and they haven’t even started paying off the initial technical debt.
The True Cost of Technical Debt
The task to clean up the original debt rolls into the next sprint as expected.
Thankfully, nothing interferes with the team this time around and Kayla is able to pay off the debt in full at a cost of a further 5 hours of time.
All told, this puts the total loss of productivity from taking on the decision to 7 hours lost. Additionally, the decision caused some customer facing defects, hurting user experience and trust.
On top of that, the bugs and technical debt payoff tasks have an opportunity cost associated with them. In other words, because the team was working on these items, they could not be working on other improvements to the software.
So, what does this mean? Should the team have not taken on the debt?
I would say no. This actually is a fairly ideal story as far as resolving technical debt. The debt was taken on in an intelligent and deliberate factor. Without that decision the company wouldn’t have made their date and would have lost a hundred thousand dollars in sales and deals.
Beyond that, the team aggressively prioritized the debt and the bugs that came out of it.
No, just because the debt cost the team a lot more development time, doesn’t mean it was a bad decision. But we do have to keep in mind when taking on debt that it will be far more than the productivity gain to pay down the debt – if it is ever paid down at all.
The Unfortunate Truth
This brings us to an unfortunate truth: the story of this team fully paying off the debt like this is highly unusual.
I would argue – based on my own experience – that most technical debt does not get resolved.
In my experience, debt can – and often does – live on until a product is retired. In fact, I’ve observed severe technical debt code being duplicated and serving as the basis for future work.
If you allow technical debt to persist in your code, it will serve as the architectural basis for future code.
Most teams don’t take on technical debt as intentionally as our team did in this article. This means they’re unlikely to gain many, or potentially any, benefits from taking that debt.
Put it another way: if you had to take on 5 hours of technical debt, would you rather it to be to make a major sale or because a developer was feeling a little lazy one day?
So what are our key takeaways here?
- Technical debt ultimately costs far more than the time you would have spent to do it properly
- Short term technical debt can be a key benefit to the organization
- Technical debt often constitutes a persistent risk to quality
- Technical debt should be monitored and prioritized
If you’d like to learn a little more about dealing with technical debt, check out a few of my other articles:
- Strategies for Paying off Technical Debt
- Communicating Technical Debt
- Addressing Tech Debt without Killing Quality
- Functional Debt: The Price of ‘Yes’
I’d also love to hear what you’ve learned about technical debt. Let me know what you think.
The post The True Cost of Technical Debt appeared first on Kill All Defects.
Top comments (6)
Great post!
I was so glad to read this. Up to this point, I was thinking "This is nothing like my experiences of technical debt". I've found that technical debt (including my own) accumulates for a combination of reasons: time pressures, lack of understanding, and -- if I'm honest -- laziness. The effects can take months or even years to be felt.
Also, technical debt is not just time wasted, but also a drain on developers' energy and enthusiasm. These effects can be even worse.
Thanks for the article. I'll make sure to check out the others you linked to.
I write and think a lot about software quality. From my experience unmitigated tech debt becomes almost sedementary in nature, forming natural buildup over time throughout a codebase and causing hacks to almost grow the architecture organically. Duplication tends to be rampant which in if itself is a huge cause for bugs, especially as new devs join code with many duplicates already and don't know all the places to change when making a new change.
I love that comparison. It becomes like a marsh that you have to wade through.
You're right, duplication is usually everywhere, even down to the duplicate comments and bugs. Learning about DRY was a lightbulb moment for me -- I instantly felt bad about all the copy-pasting code that I had done up til then.
The biggest factor in the calculation should be the "key sales and commitments". That could mean two weeks of extra development time for other features, so +80 hours.
Also, by finishing the feature it could be that the client realizes the feature was not critically important and it works good enough, so it doesn't need to be developed further. +5 hours
My point is, the true cost of technical debt is more than development, it's also early decisions, releasing a feature earlier than competitors, learning faster, ...
It's so awesome to see someone actually quantify what 'smelling fishy' actually means and leads to!
An awesome post! 💯
There are a lot of code analysis tools out there that can automatically identify code pattern / style debt or duplication. They don't catch high-level design issues, however. Many of these tools try to associate an hour or day cost per violation too, so it's out there. SonarQube is one to look into. I also love NDepend for .NET Code. Just bear in mind that there's more to debt than things that machines can automatically identify.