Good management of technical debt makes the difference between a successful and unsuccessful software project. Ignoring or failing to recognize tech debt might lead to higher development costs and low financial returns. So given the stakes, understanding and dealing with technical debt should be a priority for software engineers and high-level decision-makers.
Technical debt or code debt is not necessarily negative - sometimes, it can be strategic leverage for your project in the long run. So if you do choose to have technical debt, there is usually a strategy, intent, and rationale behind it. And although it's risky, it can be greatly beneficial. Almost every business has some degree of tech debt - the trick is knowing how to identify and manage it. This blog post helps you do just that, so let's look at what technical debt is, what kind of tech debts there are, how they impact your development process, and how you can manage it.
Table of contents
What is technical debt?
Types of technical debt
The main causes for technical debt
➤ Deliberate technical debt
➤ Unintentional technical debt
➤ Martin Fowler's Technical Debt Quadrant
What type of technical debt should I avoid?
Can I manage technical debt?
Technical debt, tech debt, or code debt is the concept of delaying or omitting work to complete a project or reach a goal faster, but which also causes more rework later in the project's life stage. We can compare it to building a house without a complete set of blueprints - construction might finish sooner, but the house will have significant structural issues that will take more time and more money to fix later.
In the software development realm, it is common to deliver a feature right away in order to understand how it will scale. Once it has scaled significantly, we can adapt it to the dimension it has reached. But stay in the loop, as we will cover all kinds of technical debt later on.
All in all, technical debt can refer to any part of web or app development, but it is usually directed to programming, particularly code refactoring. And just like financial debt, code or tech debt accrues interest - the longer the debt or backlog of ignored issues build up, the more costly it becomes to rectify.
In a McKinsey survey conducted in 2020, CIOs reported that 10 to 20% of the technology budget allocated to new software is diverted to fixing issues related to technical debt. More concerning still, CIOs estimated that tech debt amounts to 20 to 40% of the value of their entire technology estate before depreciation. This translates into hundreds of millions of dollars of unpaid debt for larger businesses.
Technical debt is a natural result of software development, and when it comes to identifying it, most experts agree on two broader categories:
- Intentional tech debt (deliberate or active debt) - happens when teams deliberately leave room for code improvement later during the development phase.
- Unintentional tech debt (accidental or passive debt) - occurs when the code quality requires improvement due to poor production.
Deliberate technical debt or active debt occurs when teams knowingly want a fast but imperfect implementation to 1) establish a presence in a quickly developing market or 2) to gather customer feedback. Deliberate tech debt is often applied when developing minimum viable products (MVP), which will be further developed and fixed according to client and customer feedback continuously. However, teams rarely have the time to go back and redesign how they initially planned, so it’s always best to collaborate with a team that has the project decently mapped out for each life stage. For instance, at Imaginary Cloud, developers go back to optimizing and improving the code of the app or software once it is live.
A good and simple example of deliberate tech debt is how Airbnb didn't bother to fix their website's favorite button. There was a moment when the button to favorite houses or rooms didn't function. Since Airbnb's focus was rapid growth at the time, they didn't mind skipping this issue. The team fixed the issue only when the company started enjoying more popularity and reached a more mature phase in its lifecycle.
Unintentional technical debt happens by accident and usually occurs when developers don’t understand market requirements or how to design an architecture to meet market requirements.
For instance, when designing a software system, a team tries to balance by thinking ahead and future-proofing their plan with simplicity and delivery. As the system evolves and requirements change, they might realize that their strategy is flawed or that the new functionality has become difficult and slow to implement.
Tech debt also has specific types, each including the specific problem within the title:
- Code debt - Usually related to poor or speedy coding or not having applied appropriate design patterns.
- Defect debt - Existing bugs, issues, and defects in the product.
- Design debt - It is all the good design concepts or solutions that were skipped in order to reach a short-time goal quicker.
- Requirement debt - Incurred during the identification, formalization, and implementation of requirements.
- Test Automation debt - Refers to all of the simple and complex processes that are supposed to be automated but are not.
- Test debt - This happens when the team starts to spend more time on test maintenance and less on creating tests to ensure the software is bug-free.
- Architecture debt - Some architectural outline decisions incur technical debt, which can negatively impact the quality of a software project.
- Documentation debt - This type of technical debt describes problems in documentation such as missing, inadequate, or incomplete papers.
- Process debt - Usually generated when processes are poor or lacking altogether to handle defects, documentation, or even tests.
While these types are very specific, the most popular is Martin Fowler's Technical Debt Quadrant which describes the kinds of debt (deliberate and inadvertent) and the choice of taking on debt (reckless or prudent).
We can identify each quadrant by assigning it a color that corresponds with its desirability: red and orange (top and bottom left) indicate warning; green and blue (top and bottom right) indicate desirability.
Let’s take each quadrant in turn and consider the role of a development team in managing the risk.
Deliberate & Reckless
This type of debt occurs when the team has the appropriate knowledge to implement the task yet consciously decides to go with a quick and poor-quality solution, usually for the benefit of quick implementation. These are some of the questions you should be asking before choosing this method:
- What is the long-term impact of this decision?
- Are you tracking the technical debt level as it’s incurred?
- Do you have a plan (and future budget) for paying it off?
- Are you doing anything to limit the consequences if this is an epic fail?
Not managing aspects like the above mentioned is what tips deliberate technical debt into the reckless territory.
It means to start anything new at a slow pace, to make sure you and anyone else working with you knows exactly what to do and what procedures to follow
Deliberate & Prudent
Deliberate and prudent tech debt is about making informed decisions and thus considering whether the payoff for an earlier release is greater than the costs of paying it off. The team recognizes the problem and its consequences but must currently provide the functionality on time. In this case, the team also plans on how to deal with the effects, considering every worst-case scenario.
Inadvertent & Reckless
Inadvertent and reckless is the least desirable type of debt you want to have - it is usually called software entropy which we explain in the next chapter. Teams are expected to grasp the fundamentals of the technologies they are using, and ignoring them will result in a buggy application with unexpected application behavior or poor maintenance. A well-trained team with up-to-date industry knowledge and best practices should be able to avoid this type of tech debt.
Inadvertent & Prudent
This is the unintentional kind of debt - it can happen despite a careful approach to the project's architecture and code. Often, it is only after a functionality is implemented or the project is completed that the team realizes that if they had designed the individual components of the application differently, they would probably end up with a better solution. So the goal is to maximize the learning opportunity so that you can move from "inadvertent" to "prudent" for more of your technical debt.
Bit rot or software entropy is the kind of tech debt you want to avoid, as we have mentioned above. It happens over time when a component or system slowly devolves into unnecessary complexity through many incremental changes, often when worked upon by several developers who might not fully understand the original architecture. This lack of skill is an inadvertent and reckless form of debt attributed to poor logic and coding practices.
You want to avoid software entropy because:
- The biggest problem in terms of debt is that the small changes actually contribute to the total amount of debt, and most of the time, the teams don’t even know it;
- These small changes can affect the whole software.
We recommend you look for squads that with a dedicated Project Manager who can hold their developers accountable by ensuring that the development process does not leave room for bit rot to occur.
According to a study conducted by Stepsize, 61% of engineering teams claim that most of the technical debt comes from the backend, specifically, in web server endpoints. Company apps and websites and general infrastructure are also parts of the codebase that accumulate a large amount of technical debt. The findings suggest that businesses could dramatically increase their productivity by paying down tech debt in these areas of their codebase.
Other main factors that contribute to technical debt include:
- Complex technical design
- Poor management
- Lack of skill
- Insufficient testing
- Suboptimal code
- Delayed refactoring
- Excessive focus on quick profit
- Lack of adaptation to standards and good practices in the initial stages
These issues can accumulate over time if not supervised, resulting in technical inefficiencies that will have to be addressed in the future. It will be best to collaborate with a competent team or partner with the right processes, plans, and time schedules. This team should make the objects visible by registering entries in the software backlog, where the issues will be assessed and prioritized for resolution.
Take the example of Twitter’s famous Fail Whale case. The platform used to crash several times and go on “emergency maintenance mode”, hurting the business. The appearance of the serene, optimistic beluga became an increasing concern as Twitter expanded to a broader audience. Hence, Twitter decided to integrate a development team that instrumented the entire system and started rebuilding every part that was about to break by shifting their backend processes to a series of programming languages that were more compatible with the Java Virtual Machine framework.
Once these changes were implemented, Twitter’s team was able to spend less time troubleshooting outages and more time developing new features, reducing tech debt, getting rid of technical inefficiencies, and, finally, providing a better user experience.
“Grinding isn’t very satisfying. It is hard to stand up in front of everyone and say, “we are going to fix things around here bit by bit with a lot of hard work.” Big flashy moves are an easier sell most of the time. But they don’t function nearly as well and are prone to complete and abject failure.”
It’s important to mention that tech debt doesn’t always come from development teams. Hiring companies or clients will oftentimes impose limitations leading developers with no other choice but to incur them. These are usually:
- Timeline or budget limitations
- Strategic decisions to test a market fit
- Flawed business decisions
- Inadequate selection of software architecture or tools
When it is deliberate:
Development teams can manage intentional technical debts by tracking the backlog when deliberately deferring work that needs to be completed. If a team can’t keep up with their promise of going back to review the code or it doesn’t have the means to do it, it is unlikely to be repaid and will turn into accidental design debt over time.
This debt is usually incurred from business decisions; therefore, stakeholders and product owners should be held accountable for the accrual.
When it is accidental:
To successfully refactor a system is a huge task, but this should be done every now and then when the system is in a steady-stade. Otherwise, the team might over-engineer the system and incur unnecessary slowdowns.
In this case, tech leads and product owners should be accountable for ensuring that time is set aside to resolve this kind of tech debt incurred by design decisions and frequently changing requirements.
Technical debt is not always a burden - it can many times be a strategic lever for success if well managed. At Imaginary Cloud, we can collaborate with you in whatever necessary stage of development to clear you of unnecessary debts, technical and design alike. Whether it’s bringing your idea to life through web and app software development or leveling up your team’s skills through team extension, we’ll make sure your tech debt is well managed every step of the way.
Click below and let us know your project requirements!