You ask your product manager to add a simple feature to the roadmap. He explains that the feature isn’t as simple as it seems because of the product’s original design. In order to build your new feature, they have to go back and make some serious changes to the product.
Uh oh. You’ve got technical debt.
Technical debt is one of the costs of software development, but like all costs, it can be avoided, managed, and even used to your advantage. In this article, we’re going to help you understand technical debt, the three main types, and how to handle them.
What is Technical Debt?
Technical debt is some kind of deficiency (or many deficiencies) in a product that makes it hard to make updates. These deficiencies usually appear in code, documentation, development environments, development practices, and third-party tools. They can greatly impact the product’s reliability, speed, security, and ability to integrate with other products.
Sadly, technical debt deficiencies become more of a burden over time. The longer they exist throughout development, the harder and more expensive they are to fix.
Image: Pictor AI
What causes technical debt? In most cases, it appears when fast, inelegant solutions are used instead of proper but time-consuming solutions. The debt accumulates over time as developers are forced to work around the inelegant solution when they make updates or add features.
Software developers often butt heads with management over the need to pay down technical debt. They argue that eliminating the debt will make the product better and help them work faster. From management’s perspective, however, it’s hard to justify investing time and money into something that already works.
To be fair, there is always some technical debt in any product. You can’t avoid it entirely. It’s important to think about technical debt as you develop your product, but not to the point where you keep starting over.
The 3 Types of Technical Debt
Not all technical debt is the same. Some technical debt can be predicted and managed. Some happens no matter how hard you try to avoid it. And just like financial debt, some technical debt can be used to your advantage. Let’s go over the three main types.
1. Intentional Technical Debt
Okay, okay - so we just finished explaining why technical debt is so bad, but in some cases, it’s created by design. In many cases, engineers know there’s a better way to do something, but they choose the quick way instead. This usually happens for two reasons (but there are others):
They need to deliver a product right now. This happens when they desperately want to create something for users to get into or for stakeholders to interact with.
They aren’t sure what the product will look like in the future, so they want to avoid over-engineering now. (e.g. Don’t build the fancy UI until we know what it’ll have on it.)
For instance, let’s say you decide to skip a code review and refactoring in order to put the product in the hands of an early customer. If that customer provides revenue and feedback that are critical to the project’s success, it makes sense to build the product “quick and dirty.” You can even assign a financial cost to the technical debt to decide if it’s worth incurring.
If you are going to make a decision like this, it's important to consider how much time you'll save by implementing the “wrong” feature and how much time it will take to refactor. In some cases, it makes perfect sense to do it quickly now and fix it later after other business and product needs have been met.
Intentional debt can also be acquired, either by obtaining ownership of an existing product or being forced to maintain legacy systems that should be replaced.
Image: Everest Group
Developers shouldn’t create this kind of technical debt on their own. It should only be incurred with the blessing of the product manager and product owner because it relates to business decisions. In fact, your product manager would be smart to track this kind of technical debt in the backlog, especially if you’re 100% sure it must be addressed in the future. If it’s not repaid at some point, it could turn into accidental debt.
2. Unavoidable Technical Debt
When you design a new system, you try to think ahead and future-proof your application. How will technologies change? What new best practices will emerge? Will your development tools change? Would the product owner change the scope of the product?
Naturally, seeing into the future is tricky, which is why some technical debt is unavoidable. As systems evolve, you might realize yours is flawed, or that it needs to be completely refactored to implement some new functionality. For instance, let’s say you have a web app that was built before the popularity of mobile devices. That could represent a lot of technical debt that the original creators couldn’t have foreseen.
Third-party systems are prime opportunities for unavoidable technical debt, especially if the system is critical to yours. If a third-party tool changes something, there’s a risk it will create technical debt. It’s important to have a very clear understanding of any third-party tool’s roadmap (and maybe a contract that requires their support). Alternatively, build your product in a manner that allows you to switch to other providers.
You can mitigate unavoidable technical debt by future-proofing your system with simple, repeatable code. Opt to control as much of the application as possible instead of relying on outside tools.
3. Unintentional Technical Debt
Unintentional technical debt is the most frustrating type. It’s the debt you should have seen coming, but missed. It’s no one’s fault but your own. You should avoid it as much as possible.
Unavoidable technical debt happens when a system slowly becomes more complex through countless incremental changes. This happens a lot when a product is worked on by many different people who don’t fully understand the original design.
In some cases, unavoidable technical debt is the result of naivety or ignorance. If a developer doesn’t know an elegant solution, he or she obviously can’t implement it. Bugs and errors from a lack of monitoring build up over time until you’re forced to fix everything. It’s the point where “work around it” doesn’t work anymore.
You can address this type of debt in three ways:
Work with experienced developers on teams with diverse skills. This way one person’s ignorance is insulated by the group. If one person makes an error, someone else on the team should be able to catch it.
Follow proper development practices, like code reviews and regular refactoring. From a management perspective, these may seem like time wasters, but they are critical to creating a quality product.
If you are hiring developers to work on an existing system, instruct them to take time to understand it and clean up any bad code. Yes, this will delay new features, but it saves money and time in the long run by avoiding technical debt.
Over to You
You can’t avoid all technical debt. It’s a part of software development. But you can control how you manage it and respond. If you take the time to understand your roadmap and business needs, you can minimize unavoidable and unintentional technical debt and use intentional debt to your advantage.
Ask the product manager on your outside development team what steps they take to address technical debt. Make sure they have reasonable solutions to respond to the three types we explained above.