What is Technical Debt?The term “technical debt” was initially coined by programmer Ward Cunningham in 1992 to illustrate that, while a software development organization may benefit from taking shortcuts to deliver application code, the “interest” from the technical debt, much like financial debt, will be far more in the long run than the costs of refactoring code to be more sustainable over the long-term. Technical debt typically happens, for instance, when a development organization takes shortcuts to deliver a minimum viable product (MVP). Although this can help an organization meet its time-to-market goals, the approach can affect code quality by baking that debt into the software. Technical debt, much like financial debt, is often the result of poor planning. In my experience, tech debt can emerge from trade-offs made by stakeholders who focus on addressing short-term business goals instead of centralizing efforts to create sustainable practices. See Figure 1.
Figure 1: Technical debt increases as short-term choices are made to address specific use cases.
Identifying Technical DebtIt can be challenging to identity tech debt within your application. Bad code in a function here or there is not a problem comparable to a shortcut taken in the early days of an application. A common pattern I see in multi-tenant applications is choosing to use a single data store (typically a relational database) instead of designing from the start to support an architecture that can scale out. This design pattern can lead to application bottlenecks with severe impacts on user experience as the use of the application grows. At that late stage, recreating the application around a scale-out model takes a great deal of rework and represents a large software project. While major architectural changes can be easy to identity, other types of technical debt can be harder to find. Examples of technical debt that development teams may encounter include changes in requirements midstream that leave unused code with potential vulnerabilities. Another example is the reliance on outdated libraries, frameworks, or even coding methodologies.
What Are the Different Types of Technical Debt?Technical debt can be classified into three common forms:
- Intentional technical debt: This form of technical debt is created deliberately as a short-term solution when the business is prioritizing short-term business needs over proper development technique. This is a premeditated choice to sacrifice code quality over delivering a product. While the approach is risky, if the MVP is refactored quickly and with a clear roadmap, the debt can be eliminated more easily than other forms of tech debt.
- Unintentional tech debt: In my experience, this debt is more common in enterprise IT organizations than in organizations dedicated to software development. When IT is not directly contributing to the bottom line in the enterprise, budgets are limited, which in turn leads software and infrastructure to fall behind and become outdated.
Even in software development organizations, changing business priorities can cause development teams to miss test cycles or shorten development cycles, leading to bugs and bad practices. This type of debt can be insidious and grow “interest” much like unsecured financial debt, becoming exponentially more expensive in both time and money to remedy.
- Environmental tech debt: This category of technical debt is most common, as it accrues over time unless teams are actively fighting against it. Operating system versions, software libraries, or changes to vendor APIs are all important components and software dependencies, and they all change over time. Unless your development teams are constantly evaluating the entire tech stack, this debt can creep up on you and ultimately lead to breaking changes in your application.
The other aspect you need to think about in your organization that can contribute to an overall sense of tech debt is tool sprawl. Correlating data from multiple tools can be challenging and, in some cases, impossible. It adds to the “toil” that your DevOps engineers must manage, either building a data engineering process to correlate data from multiple tools, or the constant context switching of using different tools which are not properly integrated. Ultimately, this limits the scalability of your system, which can inhibit the growth of your business.
Figure 2: Managing technical debt can be tricky.
Managing Technical Debt Best PracticesCareful management is required to manage and remediate technical debt. Here are some common approaches:
- Include tech debt in the scrum process. Managing debt needs to be proactive—it is not enough to include debt items on your backlog; they need to be actively managed and addressed. DevOps teams should be measured on this criterion to ensure it is a priority.
- Manage code quality. Through software engineering and best practices, you can avoid collecting code debt as you do new development. Shipping low-quality code tends to entail the use of detrimental shortcuts in place of proper development.
- Make schedules consistent. The worse thing that can happen to code quality is for schedules to get crunched. A shortened time frame means less time for planning and software engineering and more of a focus on prioritizing delivery over high quality. This is by far one of the most common causes of technical debt.
- Consolidate disparate tools. While it’s easy to think implementing more tools will provide additional visibility, the resulting tool sprawl this mindset can cause isn’t just costly and inefficient; it can cause more confusion, frustration, and disjointed data, driving teams further apart instead of bringing them actionable insights. Conducting periodic assessments of your tech stack can allow for meaningful conversations about specific reporting and functionality needs. You may find you’re using tools with overlapping functionalities that can be retired (saving money!) and consolidating multiple tools in favor of a common solution with the same functionalities can allow for shared visibility across teams, which can result in more agile workflows.