What is Technical Debt in Agile?
You are most likely familiar with the concept of financial debt: the act of taking out a loan to get something now, then paying it off later with interest on top. This is similar to how technical debt works. A software development team will take a shortcut, such as making a sub-optimal code or design decision, to achieve a short-term gain, then go back later to add or revise the code. The result sacrifices quality in exchange for speed and cost savings. Of course, just like financial debt, unpaid technical debt accrues more interest over time, making it harder to repay.
Defining Technical Debt
In software development, technical debt is the consequence of prioritizing delivery over performance. The term was first coined by software developer and co-author of the Agile Manifesto, Ward Cunningham, in a 1992 article on the WyCash portfolio management system.
In the article, Cunningham had to justify the need to direct resources to refactoring (the restructuring of existing code) to a non-technical audience. He did this by comparing technical complexity to financial debt, stating, “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.”
Consequences of Technical Debt
Since then, technical debt has become common practice in software development, and the source of heated debate.
Critics argue that managing technical debt is costly and time-consuming. According to McKinsey, 10 to 20 percent of the technical budget on a new product is diverted to resolving issues related to technical debt. A 2018 report by Stripe revealed that, on average, developers spent 41.1 hours at work per week, and 13.4 of those hours were spent on managing technical debt.
Proponents of technical debt argue that the practice helps companies speed up development, be first to market, and add value to their products with a steady stream of new features, functions, and usability improvements. Many experts agree the practice is inevitable, especially in the software market, where fierce competition forces companies to release products under tough time constraints. Even large companies like Stack Overflow assume some technical debt to meet customer demand.
For companies, the challenge then is to not outright avoid technical debt but strategize their approach to it. This way, they can leverage it to get something of high value in the short term – i.e. determine product and market fit, meet customer demand, and seize emerging opportunities – then gradually pay it off in a timely, efficient manner.
Types of Technical Debt
Intentional and Unintentional
In 2007, CEO and Chief Software Engineer of Construx Software, Steve McConnell, released a white paper called Managing Technical Debt. In it, he proposed a clear distinction between unintentional and intentional debt. In his own words, he referred to unintentional debt as, “… the non-strategic result of doing a poor job” and intentional debt as when “… an organization makes a conscious decision to optimize for the present rather than for the future.” He then emphasized the importance of keeping unintentional debt to a minimum, so that companies could safely absorb more intentional debt for strategic reasons.
After the publication of this white paper, more voices entered the conversation, each one sharing their own interpretation of technical debt, and the different ways it could be categorized.
Technical Debt Quadrant
Two years later, British software developer, Martin Fowler, expanded on McConnel’s theory with the Technical Debt Quadrant. The purpose of the quadrant was to define technical debt by four distinct categories, based on intent and context. For intent, the quadrant posed the question: is the technical debt deliberate or inadvertent? It would then ask: is the technical debt prudent (done with care and thought for the future) or reckless (done without care for the consequences)?
Based on the Technical Debt Quadrant, technical debt could fall into one of the four categories:
Prudent-deliberate – The team intentionally takes on debt and plans to fix it.
Prudent-inadvertent – The team unintentionally takes on debt but realizes it and then plans to fix it.
Reckless-deliberate – The team intentionally takes on debt and has no plan to fix it.
Reckless-inadvertent – The team accidentally takes on debt and has no plan to fix it.
Ontology of Terms on Technical Debt
In 2014, a group of academics released a white paper that expanded on the two previous theories.
Published by the Software Engineering Institute, the Towards an Ontology of Terms on Technical Debt paper did not categorize debt based on intent or context but on the nature of the debt. The paper proposed 13 distinct categories for technical debt. These included Architecture, Build, Code, Defect, Design, Documentation, Infrastructure, People, Process, Requirement, Service, Test Automation, and Test Debt.
These categories help development companies identify and target specific types of technical debt. Take Design Debt for example. This refers to the imperfections in a software product’s user interface. An Agile team may choose to omit good design concepts and solutions, on purpose, to reach a short-term goal, such as pitching to an investor. If the pitch is successful, the team can then ‘repay the debt’ and revisit the design to make it more user-friendly, more visually appealing, and more compatible with different devices.
The Technical Debt Ratio
The Technical Debt Ratio (TDR) is the cost difference to fix a section of code compared to building it. Development teams use the TDR to convince stakeholders that paying back a particular debt is more worthwhile than letting it grow, and that the debt itself is a worthy investment.
The most commonly accepted TDR equation is:
(Remediation Cost ÷ Development Cost) × 100 = TDR
The Remediation Cost is the cost to fix a software product, and the Development Cost is the cost of developing that product. The right TDR will depend on the project size and scope, as well as the team’s defined standards. Co-founder and CEO of the technical debt measuring software company, Stepsize, Alex Omeyer, says that a TDR of 5 percent or less is ideal.
How Development Teams Manage Technical Debt
Smart Agile development teams have technical debt down to a science. They know how to measure, monitor, and maintain all kinds of technical debt, from readability issues to sub-optimal design to lack of technical documentation. Any shortcuts are reported, accounted for, and resolved at a later time. There is no ‘poor programming’ or ‘lazy design choices,’ but intentional compromises with predicted outcomes.
Here are just some of the many ways that development teams reduce or eliminate technical debt:
Establish technical debt standards
Development teams should be on the same page about technical debt. This includes how they define technical debt and how they identify, track, manage, and resolve technical debt. There should be a clear distinction between poor work and technical debt. Furthermore, there should be a universal standard for “done.”
For traditional development teams, “done” usually means an item is good enough for QA to test. This approach can lead to bugs that creep into the development cycle, which build up over time. So, by the time QA gets their hands on a product, it is riddled with layers upon layers of bugs.
Agile teams, however, define “done” as when a feature or function is ready for release – not just good enough for testing. This means, the team does not move on to the next step, until the current item is customer ready.
Automated testing is an effective way to reduce technical debt. When a developer discovers a bug, they should do an automated test to demonstrate it. That bug should then be promptly fixed. Following this, the same automated test should be run again to ensure the bug is fixed and the test passes.
To refactor code is to restructure computer code without changing or adding to its external behavior. It involves making code changes that are so minor they are unlikely to introduce new bugs or errors. As a result, this preserves the existing source code’s behavior and functionality.
Refactoring helps reduce technical debt by converting ‘dirty’ code (an informal term used to describe code that is hard to read and maintain) into ‘clean’ code (code that is easier to read, understand, and maintain). While code refactoring does not resolve code behavior or functionality issues, they do make the code easier to read, which, in turn, helps the development team maintain and scale the code.
Take Control of Technical Debt
Technical debt is a reality for even the most talented software development teams. What does this mean for hiring clients? Take the time to understand the approach that a development team takes to identify, manage, and resolve technical debt.
Trustworthy and reputable teams will be open and transparent about their approach to managing technical debt. While less trustworthy teams may use vague language to confuse clients, be dismissive, or even outright lie by saying that they can avoid technical debt altogether.
These days, the accrual of some technical debt is an acceptable part of the development process, and when handled properly it can speed up development and accelerate time to market.
Topics: Technology Trends