“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. Every minute spent on not-quite-right code counts as interest on that debt. Entire engineering organizations can be brought to a stand-still under the debt load of an unconsolidated implementation.”
— Ward Cunningham, 1992
The concept of debt is fairly straightforward: you can pay now, or you can pay later with interest. Any CEO knows their company’s debt load or can ask the CFO when they need a reminder. Yet, even though those same executives understand that software and digital strategy are key to the long-term success of their companies, the concept of technical debt (TD) is still not well understood outside of IT circles, despite this year being the 25th anniversary of Ward Cunningham coining the term. Technical debt is traditionally associated with software development, but it is applicable to any discipline where technology is being used to solve problems and glean insights. Like real debt, TD can be simple debt or it can accrue interest in the form of increased maintenance, complexity, lack of flexibility, and manual labor.
Over the years, we’ve lived through the decisions and consequences of taking on technical debt. Below, we describe why technical debt occurs and provide our views on how to manage it.
Why technical debt happens
In and of itself, technical debt is neither bad nor good — it is a choice. Like financial debt, it can be used as a tool to provide leverage to address a lack of time, resources, or information. Unlike financial debt, however, frequently it is the people towards the bottom of the org chart who are empowered to make the decisions as to when and how much to take on. But these decisions have broad consequences for how a company pursues its goals, and executives need to play an active role in shaping their TD strategy.
For high-functioning teams, technical debt is the result of doing a cost-benefit analysis. For example:
- A software team may work with product owners to decide that it is better to get a product, update, or feature out and into users’ hands, knowing they’ll likely have to tune it over time, than to attempt to build it perfectly from the start.
- In order to fix a production issue, an engineer may deploy a brittle, stopgap fix in order to buy the team time to diagnose and develop a better long-term solution.
For other teams, TD is not a deliberate choice. They can create TD due to shortcomings in leadership, documentation, skill level, collaboration, and process. For example:
- Business executives may create TD by requiring constant changes, not planning well, and over-promising custom deliverables to clients and stakeholders. In order to meet their deadlines, developers take shortcuts and are not allotted time to remove legacy code. If left unchecked, the team will be left with a complex, fragile code base filled with vestigial components that people are scared to touch because every change results in at least one unintended consequence.
- Development teams may create TD by not articulating the need to address TD in a timely fashion. Often developers make the choice to incur TD in order to make up for underestimating a task and then fail to follow up with product owners to properly prioritize and schedule paying it down.
Technical debt tends to accumulate naturally over time. In an example from our own company, our original user-interface (UI) had been outsourced, and as we built our own internal engineering team, we took on more ownership of the UI. At the same time, we were also a typical early-stage product company that was developing features as quickly as possible and innovating as we went. After a few months, the team broached the topic of paying down technical debt with the CEO. We didn’t want to just address the debt, we essentially wanted to start over and rewrite the UI. Why? For one, the UI had become fragile as we built out more and more features. Simple changes required more effort and more testing. The current implementation was also lacking several large, critical features that were going to require significant effort to implement. We saw the UI as more or less a prototype, and recognized its shortcomings as a stable platform.
We presented to leadership the three choices: (1) continue doing what we had been doing; (2) address the debt in the existing UI; or (3) come up with a plan to transition to a new, 2.0 version. As a team we discussed the implications of each. Everyone agreed that the status quo was not really an option, and we didn’t consider that for long. It came down to which would be better: trying to fix a fragile system or starting fresh with a deeper understanding of where we wanted to go.
Before we could make this decision, however, we needed to consider more than just the technical justifications. A major consideration was the impact on both our existing clients and prospects. In the end, we worked out a plan that enabled us to satisfy both our business and technical needs. We agreed that we’d freeze all feature development on the existing UI and only take on TD to work on critical patches for it. In parallel, the team would begin working on 2.0.
None of this was easy; it required compromises by all parties. Throughout the execution of the plan, we met and discussed the TD, opportunity costs, and risks of making or not making each change to the original UI. Needless to say, there was friction, but the timing was right. Had we waited much longer, we would have lost a window of opportunity; had we started much sooner, we would have had fewer insights into what our 2.0 release really required to be successful.
What to do about technical debt
When you’re facing down a backlog of technical debt, with all of its complexities and follow-on effects, it can be hard to see the forest for the trees. To address technical debt head-on, we take a three-phase approach: assign, assess, and account.
Assign – Executives should make engineering and technical leaders responsible for measuring TD, just as a CFO is responsible for reporting financial debt at executive briefings. At a monthly executive meeting, an engineering leader should be able to brief the executive team on how much TD there is so the team can best plan for resource allocation. You should also make sure the services team that implements solutions specific to client demand is working closely with product and software developers to implement generalized solutions to those issues. The goal is to empower your teams to move toward a comprehensive, quantitative understanding of the company’s TD.
Assess – To facilitate this move away from scattered, anecdotal evidence of technical debt, companies need to create a way for their teams to measure and discuss TD. Most engineering teams are probably already tracking technical debt in their issue tracking system. If not, they could start somewhere simple like a wiki page. For planning, transparency, and forecasting, it’s important that these measurements do not stay siloed in your IT department. Business executives should schedule regular updates on TD from the technology team with an understanding that it is a natural consequence of how the organization operates as a whole.
Account – Plan for and schedule technical debt payments in two ways. First, leave some room in every development cycle (aka sprint) for developers to address TD they encounter. Second, know that some TD is too large to just be swept under the rug or cleaned up when encountered. As you learn when and why to adjust away from quick fixes toward permanent solutions, you will see the value in scheduling larger efforts to address TD into your delivery schedule.
Companies large and small devote significant portions of their budget to IT and do not have a firm grasp on the debt that they accrue. Knowing and managing versus not knowing technical debt levels will separate top performers from the rest as large enterprises and SMEs become increasingly dependent on technology for competitive differentiation.