Technical debt is a term that often gets thrown around in the tech community, but what does it really mean? As someone who has navigated the complexities of software development for years, I can tell you that technical debt is a significant challenge for organisations. In simple terms, technical debt refers to the future costs incurred when you or your team opt for quick, short-term solutions instead of more robust, long-term approaches.
Understanding Technical Debt
Knowingly Introduced Debt: This occurs when you make a conscious choice to prioritise speed over quality. For instance, if you need a feature delivered quickly and decide to implement a workaround that isn’t ideal, you’re knowingly adding to your technical debt.
Unknowingly Introduced Debt: Sometimes, decisions made in the past may have seemed sound at the time but become problematic as the system evolves. A classic example is the Azure DevOps team’s initial architectural choices regarding work item tracking. They designed their system with the assumption that no one would need more than 1024 custom fields. Fast forward, and they found themselves needing to refactor their entire system to accommodate the reality of their users’ needs.
The Real Cost of Technical Debt
Technical debt can manifest in various ways, and it’s crucial to differentiate between actual technical debt and other issues that might be mislabelled as such. For example, writing poor code and shipping it without due diligence isn’t technical debt; it’s simply incompetence.
In a competent team, we can categorise technical debt into two types:
Known Technical Debt: This is the debt you’re aware of and have chosen to accept for the sake of expediency.
Unknown Technical Debt: This is the debt that creeps up on you, often as a result of past decisions that seemed reasonable at the time but have since become liabilities.
The Importance of Paying Back Technical Debt
One of the most significant challenges with technical debt is that it’s not like a traditional debt secured against an asset. If you stop paying your mortgage, the bank can repossess your house. But who is ensuring the quality of your product against technical debt? There’s no safety net; it’s an uninsured risk that you must manage proactively.
I often reflect on the Azure DevOps team’s journey. They transitioned from a waterfall model, shipping updates every two years, to a more agile, continuous delivery model with three-week sprints. This shift revealed the extent of their technical debt, as they faced numerous issues stemming from decisions made during their previous development cycle.
Over eight years, from 2010 to 2018, they learned the hard way that they needed to pay back their technical debt. By focusing on this, they increased their production from 25 features a year to an impressive 360 features by 2018.
Strategies for Managing Technical Debt
Here are some strategies that I’ve found effective in managing and paying back technical debt:
Prioritise Refactoring: Make it a part of your regular development cycle. Allocate time specifically for addressing technical debt.
Close Feedback Loops: Shortening feedback loops allows teams to identify and rectify issues more quickly, leading to better decision-making and less accumulated debt.
Focus on Quality: Encourage a culture where quality is paramount. This means not just delivering features but ensuring they are built on a solid foundation.
Measure Progress: Track the number of features delivered and the quality of those features over time. This will help you see the tangible benefits of paying back technical debt.
Conclusion
In my experience, the value of paying back technical debt cannot be overstated. It’s not just about reducing the burden of past decisions; it’s about enabling your team to deliver more value with the same resources. The Azure DevOps team’s journey is a testament to this. They didn’t set out to deliver more features; they aimed to clean up their processes and systems. Yet, in doing so, they found themselves delivering more than they ever thought possible.
So, let’s stop managing technical debt and start paying it back. The long-term benefits will far outweigh the short-term gains of cutting corners. Embrace the challenge, and you’ll find that a well-maintained system is the key to sustainable success.
Technical debt is a huge problem for organisations. I want to quickly define technical debt. Technical debt is future cost that you incur when you or your team prioritise quick short-term solutions over more robust long-term approaches. Right, so anytime you make a choice to do something fast but wrong because you need it fast, you’re knowingly introducing technical debt. You can also unknowingly introduce technical debt, i.e., we made some architectural choices. They were good choices at the time, but now they’re no longer good choices. Technical debt can appear over time.
I’m thinking of a transactions system, and we supported X number of transactions per second, and our platform of choice was reasonably priced and was able to support well beyond what we thought we were going to transact. But now we’re transacting a lot more than that, and we’re reaching the limits of the system that we chose. A great example of that is the Azure DevOps team when they originally envisaged work item tracking fields. A work item was a row in a database, and fields were a column. Those of you who are software engineers have already figured out what the problem would be with that in that you can only have 1024 columns in a SQL database.
So they not quickly, but they did hit limitations on the number of columns that you could have for custom fields because who would have more than a thousand fields on a work item? But yeah, people do. They do exist, and people do that, and it was totally within the system. So they thought, “We’ll never have a thousand fields,” or somebody made that decision, just like the two-digit date decision back in the day. So they had a lot of work to go back and refactor, not just refactor the system but write the capabilities to refactor the data on upgrade for their customers into a format where each field was a row in a database rather than in a column.
So then you have unlimited capability for fields and data, and those types of decisions, either knowingly made decisions that result in something that’s not quite the way it needs to be or unknown ones, are where most technical debt comes from. There are other issues that people call technical debt which aren’t necessarily technical debt, but most people lump it all together and say technical debt. I think I often do as well, and that’s I’ve written bad code and shipped it. That’s not technical debt; that’s incompetence.
Right, so within the context of a competent team, there’s known technical debt and unknown technical debt. But there’s another thing that we call technical debt, which is just shipping bad code, making poor choices, knowing that they’re poor choices, and not doing anything about it. Right? Shipping bad code. Stop shipping bad code would be the way you pay that one back. But for technical debt, you need to pay it back. You need to prioritise paying back that technical debt. Think of it more as an unhedged fund rather than a debt like a credit card.
Most debt is secured against something, secured against an asset. If you stop paying your mortgage, then the bank comes and repossesses your house and gets their money back, right? And maybe you get some leftovers because you paid some of your mortgage. But who’s ensuring your product quality? Who’s ensuring your product against your technical debt? There’s no insurance; it’s uninsured from that perspective. Nobody can magically come along and pay back all the debt. It’s not insured at all, or sell something and pay back. We claim an asset, so it’s something you’re going to have to deal with, and you can’t let it get out of control.
And there’s a lot of unknown technical debt. I mean, that’s like, I mean, I use the Azure DevOps team a lot as an example, but they’d been a waterfall team for many years, shipping once every two years. And then they moved to a more continuous delivery three-week model, and they found that they made lots of poor decisions, right? That weren’t necessarily poor decisions within the context of two years, but they couldn’t really see the impact of the technical debt, the choices that they’d made, deliberate and undeliberate, right, on their ability to deliver product and their ability to deliver value.
But I have a graph of, I think it’s 2010 through to 2018 for that product team, so eight years of development, and they effectively go by moving to continuous delivery, moving to three-week sprints, moving to that faster cycle from a two-yearly cycle and running into issues with that. And every issue they’re running into, paying it back, right? Paying back the reason that they made those choices, which were perhaps valid reasons at the time, but you still need to pay it back. It doesn’t matter whether it was a valid reason or not.
And paying it back and doing the work, they actually went from 25 features to production each year in 2010 to something like 360 features to production in 2018. So by focusing on paying back their technical debt, enabling their engineers to close the feedback loops, then shorten the feedback loops, three ways of DevOps, right? Closing the feedback loops first, then shortening them. And that act of shortening the feedback loops can massively increase the amount of value that you can deliver long term.
And that’s the value of paying back technical debt, of managing technical debt well, is that you can go from removing those limitations to maximising the value that you deliver in your product with the same number of people. That was the Azure DevOps team literally went from 25 features to production each year in 2010, worked very hard to pay back technical debt, and were able to, even in the first year of focusing on paying back technical debt to get their new way of working up and running, they went from 25 features to production to 68 features to production within that one year.
And they weren’t even focused on delivering more features; they were focused on, “Let’s deal with our crap,” and “Let’s figure out how we deal with those problems.” And they still delivered more features. That’s the benefit of paying back technical debt. That’s the benefit of having a slick, easy system to add features to your product, and that’s what everybody needs. Don’t manage technical debt; pay it back.