Technical Debt
Technical debt is a concept coined by Ward Cunningham in 1992, originally as a metaphor to explain to non-technical stakeholders why time needed to be set aside for code refactoring. As Cunningham put it, “Shipping first-time code is like going into debt. A little debt speeds development so long as it is paid back promptly with a rewrite… The danger occurs when the debt is not repaid.”
Let’s look at some examples of technical debt—how it’s incurred, inherited, and paid down.
Technical debt can be categorized into two broad types: deliberate and inadvertent. Deliberate debt is a conscious choice made to accelerate delivery, often with a plan to address it later. Inadvertent debt, on the other hand, occurs without intent—often because the impact wasn’t foreseeable when the code was written or decisions were made based on immediate needs.
Taking on deliberate debt is acceptable if documented properly. This usually involves noting the decision in an issue-tracking system and estimating when the debt would need to be addressed. For example, one of my teams once built an API and web application for banks that allowed them to offer loans. Since only two banks were initially involved, we chose to hard-code configurations rather than building a more flexible but time-consuming solution. We planned to refactor once more banks joined, but as it turned out, we never exceeded two banks, so our decision was justified.
Inadvertent debt tends to reveal itself only when it becomes problematic, disrupting timelines and causing unplanned rework. For instance, our underwriting application contained logic to ensure loan APRs met state laws. This made sense initially but became an issue when the same functionality was needed in another application process. Had we built this as a microservice from the start, we would have avoided this complication.
Technical debt doesn’t go away on its own. Left unchecked, it compounds, slowing development and demotivating teams. Here are some strategies I’ve used to manage it:
1. Dedicated Time for Debt Repayment: Engineering teams can allocate a set portion of their time to address technical debt. This might look like dedicating one sprint in five to debt repayment or reserving 20% of planned work in each sprint.
2. Cost-Benefit Analysis: Another approach is to estimate the cost of living with the debt versus fixing it and prioritize the work accordingly. While this isn’t easy, quantifying the impact helps stakeholders understand why it’s important to address.
Ignoring technical debt isn’t an option. I once took over a team bogged down by an application overwhelmed with technical debt. Only 20% of their time was spent on new features; the rest was swallowed up by legacy issues. Demonstrating these costs helped secure buy-in to tackle the problem.