A Useful Guide to Technical Debt in Agile (and How to Stop it Getting Out of Control)
Agile teams are constantly striving for excellence and continuous improvement which means they’re more likely to take on technical debt.
Properly managing technical debt can make a difference in the success or failure of an agile team. But ignoring technical debt can lead to higher development costs, longer project timelines, and lower business value.
Technical debt in agile is the cost of rework that accumulates when code is not clean, well-designed, or well-tested. Agile teams are proactive about managing their technical debt—they constantly refactor their code to keep it clean and they continuously integrate new code to keep their design up-to-date. While not all technical debt is harmful, it can become a problem when it starts to accumulate.
In this guide, we'll share the basics of technical debt in agile, how we’ve done it for our clients, and a few actional steps you can take to keep your technical debt manageable.
Table of contents:
Ready to build your own custom software with a team that cares about you and your processes? We’re not code monkeys, we care about you.
What is technical debt in Agile software development?
For example, if you code something quickly to meet a deadline, that might create technical debt because you know the code isn’t perfect. You incur this debt when you make a decision that saves time or money in the short term but will likely need to be addressed later.
Once the deadline has been met, you'll need to go back and "clean up" the code to meet the best Agile technical practices (and it's easier to maintain). This additional work is the "interest" on your technical debt.
Technical debt can also refer to design or architectural decisions that make future development more difficult.
For example, if you build a feature using an older technology instead of investing the time to learn a new one, you might incur technical debt. In this case, the decision might have been made because the new technology wasn’t well understood at the time or because there was a lack of resources.
4 types of technical debt (and examples)
According to Julian Alessandro, Co-Founder, Principal Engineer at NaNLABS, there are mainly two kinds of technical debt. He says the first one is “Debt that you’re aware of, that is part of the estimation of a feature. This kind of debt can be registered properly and in a timely manner. It can be repaid later and included in a future sprint.”
And the second type is “Debt that ‘appears’. This is fairly normal when working on legacy code. You can find improvement opportunities or a future refactor that can become technical debt. You can also find code that’s far from being optimal, that you can live with and add new features, but that you need to improve.”
While Matias believes that types of technical debt are “contextual of every team and project” he finds Matin Fowler’s categorization of each debt into reckless/prudent and deliberate/inadvertent quite interesting.
Martin Fowler's "technical debt quadrant" theory states 4 types of technical debt:
Deliberate and reckless
Deliberate and prudent
Inadvertent and reckless
Inadvertent and prudent
Here's what each type of technical debt looks like in practice:
The "technical debt quadrant" theory lists types of technical debts widely accepted in the software industry
Also known as planned or intentional debt, deliberate technical debt is when a decision is made with complete knowledge that it's going to create debt. This type of debt is usually incurred when there’s a trade-off between time and quality.
1. Deliberate and reckless debt consequence of bad software architecture since your team believes they don't have the time to build or fix it the right way. For example, if you're under pressure to release a new feature quickly, you might make the decision to cut corners in order to meet the deadline. In the long run, this debt will need to be paid off with extra time and resources to go back and fix the code.
2. Deliberate and prudent debt is small and manageable. For example, you might choose to use older technology for a new feature because it will get the job done and you can upgrade later when you have more time. This type of debt is usually well-documented so that the team is aware of it and can resolve the issues.
Also known as accidental or unintentional debt, inadvertent technical debt is when a decision is made without realizing it will create debt. It can occur when there is a lack of knowledge, poor coding practices, workflows, and inefficient coordination within the team.
3. Inadvertent and reckless debt is usually the result of a rushed decision or lack of knowledge around Agile practices. For example, if you're building a new feature and you don't know how to do it the right way, you might make a quick decision that creates more work down the line. Over time, this can add up and create a lot of technical debt.
4. Inadvertent and prudent debt occurs when a team implements best practices at every stage of the roadmap and still generates debt. For example, a new technology might be released after you've already built a feature using an older one. In this case, you didn't know about the new technology at the time and there's no easy way to upgrade without incurring more debt. But the team can resolve issues since they're a part of the prudent team.
How tech debt can cause challenges for your team
“I don’t consider Tech Debt an agile technical practice.” Says Matias, “Instead, this is something to be aware of, that even the finest and greatest software development teams generate. The main point is to keep it under control and take care of the codebase internal quality so it doesn’t slow down team productivity.”
If managed properly, technical debt can help ensure Agile continuous improvement and speed up the decision-making process. But when it gets out of control, it can lead to:
1. Low-quality code
When developers cut corners to meet deadlines, they might not have time to write high-quality, well-organized code. As a result, the developers who join the team later might have a hard time understanding the codebase, making iterations, and dealing with missteps. The poor code design leads to a backlog of technical debt that needs to be fixed.
Code review in Agile is one way to prevent low-quality code from getting into the codebase in the first place. By requiring developers to submit their code for review before it's merged into the main branch, you can catch errors and ensure that the code meets the team's standards.
2. Progress blockers and product backlog
Since your team has to spend time fixing old code instead of working on new features, a large backlog of technical debt can bring a halt to progress. If the technical debt is not well-documented, the team cannot prioritize which issues need to be fixed first. As a result, they might waste time fixing low-priority issues while more important ones remain unresolved.
3. Poor user experience (caused by defects)
If technical debt is not managed properly, it can lead to defects in the code. These defects can cause a poor user experience, which leads to customer churn. In some cases, the team might be aware of the issues but they don't have time to fix them or the team might not even be aware of the issues because they're buried in the code. Either way, the end result is a subpar product.
4. Low team morale
When your team is constantly struggling to keep up with their workload, or they're constantly fixing defects instead of working on new features, it can lead to low morale.
According to Matias, “In the mid or long run, it (technical debt) could impact the team by favoring bad practices and driving low morale. This also creates team attrition which also has a negative impact on the software internal quality.”
Technical debt can also cause problems for product management teams. For example, if you're trying to estimate the time it will take to complete a project, you need to take into account the time it will take to fix the technical debt. Otherwise, you might end up over-promising and under-delivering.
How to handle technical debt in Agile projects
The best way to avoid getting into a situation where technical debt is out of control is to proactively manage it. Here's how we do it at NaNLABS.
1. Refactor the source code
Code refactoring is the process of restructuring the existing code of a program into cleaner, more readable code without changing its functionality. Code refactoring is important because it can help prevent technical debt from getting out of control.
When you have a lot of legacy code, adding new features or making changes without introducing defects can be hard. Refactoring the code can help make it more manageable and easier to work with.
Our team at NaNLABS used code refactoring to help our client CyberCube, an analytics platform that enables re(insurance) placement, underwriting decisions, and portfolio management optimization.
The legacy system was already in place, and we had to introduce a new software system. Our development team wanted to build on a complex existing code, and refactoring it was a good idea. We started by identifying common responsibilities and components that could be reused. This helped us decrease the amount of code that needed to be written, and it made the code more maintainable.
2. Stay on top of technical debtmetrics
Very often businesses don't realize how much technical debt they have until it's too late.
Tracking technical debt at NaNLABS
There are a few different ways to measure technical debt, but here are a few of the most common:
Code can become complex over time, especially when multiple teams contribute to the same codebase. Code qualitymetrics assess the overall complexity and health of the code. This includes things like code duplication, code coverage, and code smells. There are a number of tools that can help you measure code quality so you can identify areas that need to be refactored.
New bugs vs. closed bugs
Every bug has a cost associated with it. Tracking the number of new bugs against bug fixes is a good way to see if your technical debt is getting out of control. If you're introducing more bugs than you're fixing, it's a sign that you need to refactor your code.
Agile software development teams often run into trouble when multiple stakeholders and teams are involved in the same codebase. Without a transparent project or code ownership system, it can be hard to keep track of who is responsible for what. Tracking code ownership can help you see where the responsibility for a particular piece of code lies and notify you when minor contributions are made.
3. Implement Agile practices
Our client, Amalgam, a software platform that allows tech-savvy individuals to build complex automated processes using their day-to-day tools, also benefited from code refactoring.
They had many technical issues like bugs, inconsistencies in defined dependencies, code that wasn’t well modularized, and high technical debt. Our team at NaNLABS implemented Agile processes to establish a workflow and improve the quality of the code.
4. Automate code reviews
Code reviews are an important part of the software development process. They help ensure that code meets the standards set by the team and that it doesn't introduce any new bugs. Code reviews can be done manually, but they're often time-consuming and error-prone. Automated code review tools can help you save time and improve the accuracy of your code reviews.
5. Follow the Agile Boy Scout Rule
The Boy Scout Rule says you should "Always leave the code better than you found it." In other words, when you're working on a project or workflow, you should try to clean up any existing technical debt. This might mean refactoring code, adding comments, or improving documentation.
Of course, you can't always stop to fix technical debt every time you're working on a project. At some point, you need to ship the product. And if you're working in an Agile environment, you need to be able to quickly adapt to changes. So how do you find the balance? "The key is to have a technical debt management strategy in place," says Matias. "You need to be able to prioritize the most important issues and work on them promptly."
Technical debt is a reality of the software development process. But if you're not careful, it can quickly get out of control. Tracking technical debtmetrics and following the Boy Scout Rule can help keep your codebase clean and manageable. And finally, having a technical debt management strategy in place will help you prioritize the most important issues and address them promptly.
At NaNLABS we've discovered that the best way to manage technical debt is to focus on code quality. We use a combination of automated code review tools and manual reviews to ensure that our code meets our standards.
And we always try to leave the code better than we found it. By following these practices, we've been able to keep our technical debt under control and deliver high-quality software products to our clients.
Ready to build your own custom software with a team that cares about you and your processes? We’re not code monkeys, we care about you.
Frequently asked questions about technical debt in Agile
What causes technical debt in Agile?
Technical debt in Agile results from taking shortcuts during development to meet deadlines. This can include using quick solutions instead of more robust ones, not properly refactoring code, or skipping over tests. Over time, these shortcuts can add up and create significant problems that can completely slow down or halt development.
What is technical debt in Scrum?
Technical debt in Scrum generally refers to anything that hinders the development team's ability to deliver features on time. This includes code that is not properly refactored, insufficient tests, or infrastructure that is not up to par.
Does Agile increase technical debt?
Agile does not necessarily increase technical debt, but if shortcuts are taken during development in order to meet deadlines, it can result in more technical debt. And, if Agile is not properly managed, it can lead to an increase in technical debt.