What is Technical Debt?
Technical Debt Definition
In software development and also in product development, the so-called “time to market” is an important competitive factor for gaining a market position.1 If companies try to shorten the duration of product development in order to place a software or a product on the market faster, technical debt can be the result.
Technical debt is the result of prioritising fast delivery over “perfect” code or a “perfect” product. It is the cumulative sum of all design decisions made yesterday and today that affect the ability to deliver value tomorrow. It is the consequence a company feels when it prioritises saving time today over future effort to adapt the software or product later. And it is an appeal to stakeholders not to postpone measures to increase the quality of software or products, because in the medium term the development time is not accelerated but slowed down.
Depending on the amount or size of the technical debt, it must be repaid in the course of software or product development through additional and higher efforts. If products are subsequently difficult to change, expand or maintain, this may “only” lead to longer development cycles, but in the worst case to the end of further product development.
The “Debt Metaphor” by Ward Cunningham
The “debt metaphor” comes from Ward Cunningham, one of the 17 authors of the Agile Manifesto and the inventor of the Wiki system2. In the course of developing a portfolio management system called WyCash3, Cunningham tried to emphasise the importance of refactorings4:
“With borrowed money you can do something sooner than you might otherwise, but then until you pay back that money you’ll be paying interest. I thought borrowing money was a good idea, I thought that rushing software out the door to get some experience with it was a good idea, but that of course, you would eventually go back and as you learned things about that software you would repay that loan by refactoring the program to reflect your experience as you acquired it”.
There are a few aspects to be gleaned from this metaphor:
- It can be perfectly fine to incur debt in order to achieve a goal more quickly or to realise an advantage, as long as the parties involved are aware that interest and repayment are indispensable. Those who subsequently fail to pay their interest regularly and repay their debts will at some point no longer be able to realise new features. In other words: refactoring is essential for the successful ongoing development of a software.
- It is desirable to gain experience that can be used to optimise a software. The “debt metaphor” thus fits very well with iterative, incremental development, extreme programming, the agile mindset, Scrum or the use of Minimum Viable Products (MVP), among others.
- It is important to find a “technical debt balance” between the benefits and the technical debt, depending on whether code is written “clean” enough to be refactored at a later stage. Clean code principles and practices help minimise debt.
Last but not least, Ward Cunningham is not concerned with implementing “bad” code that will be replaced by better code at a later date:
“You are wise to make that software reflect your understanding as best as you can, so that when it does come time to refactor, it’s clear what you were thinking when you wrote it, making it easier to refactor it into what your current thinking is now”.
So code should always represent the current understanding to solve a problem through software. And code should be improved through refactorings when new knowledge or better understanding is gained. And that means: technical dept is not built up intentionally, but it arises involuntarily in the course of a development! By the way, this is also due to technical progress.
Different perspectives on technical debt
Although “technical debt” or “tech debt” goes back to Ward Cunningham, numerous other software developers have also commented on it.
- Robert C. Martin reinforces Cunningham’s perspective and differentiates between technical debt and bad code based on laziness or unprofessionalism, whose implementation can never pay off. “Tech debt” is therefore not an anti-pattern.5
- Shaun McCormick sees technical debt as positive, necessary and intentional because it allows companies to get their products to market quickly and at the right time, and that is more important than high quality code.6
- Alistair Cockburn argues that “technical debt” jeopardises development at a steady pace and thus the willingness to take on debt contradicts the core values of agile software development.7
- Steve McConnell takes a different position and distinguishes between intended and unintended, as well as short-term and long-term debt. Unintentional debt occurs, for example, when inexperienced software developers unwittingly write bad code. By “long-term debt” he means strategic decisions, such as the choice of a platform or a database, which lead to numerous challenges in the future.8
- Martin Fowler also uses the term “cruft”. Cruft is mediocre code that is redundant, poorly designed or even unusable. Technical debt corresponds to the development work needed to eliminate the consequences of implementing mediocre code. In his view, debt can be deliberate or indavertent, and it makes a difference whether it is prudent or reckless. This classification is reflected in the “Technical Debt Quadrant” he designed.9
Reasons for tech debt
From the above perspectives, key reasons for tech debt can be identified:
the deliberate decision for a “quick” solution or implementation (Cunningham, Martin and McCormick),
and the unintentional creation through cruft or lack of knowledge combined with reckless approaches that do not value quality (McConnell and Fowler).
And what causes can lead to “tech debt”? Among others:
- professional pressure,
- internal or external deadlines,
- customer or market expectations,
- inadequate internal or external communication,
- incorrect estimation of effort,
- inadequate quality and testing processes,
- lack of quality awareness on the part of developers,
- missing or postponed refactorings,
- distinction between internal and external software quality,
- abandonment of standards, principles or established practices,
- focus on other software components,
- lack of ability to learn from mistakes, or lack of leadership and
- lack of leadership and ownership.
The list can easily be extended, especially if every deficiency of a software is classified as “debt”.
Types of technical debt
How can technical debt be classified if it is not only understood as a consequence of a conscious, strategic prioritisation or decision? The Software Engineering Institute at Carnegie Mellon University has defined 13 types:10
- Architecture Debt – e.g. due to the development of monoliths, the abandonment of modularisation or challenges in the transition to microservices
- Build Debt – e.g. by not using continuous integration or continuous delivery
- Code debt – e.g. through the violation of common principles such as DRY or KISS
- Defect Debt – e.g. by not implementing bug fixes
- Design debt – e.g. through the violation of design principles with negative effects on the user experience
- Documentation Debt – e.g. due to missing coding and documentation guidelines
- Test Debt – e.g. due to lack of test coverage or insufficient code coverage
- Test Automation Debt – e.g. by not automating unit tests
The following types can also be classified as organisational debt:
- Infrastructure Debt – e.g. due to impediments such as missing software licences or non-functioning hardware
- Service Debt – e.g. by determining the software structure based on the organisational structure of the producer (Conway’s Law)
- Requirement Debt – e.g. due to faulty backlog refinement or an undefined system context
- People Debt – e.g. with employees who do not want to learn or implement anything new, who do not perceive themselves as a team and do not feel bound to commitments such as a Definition of Done
- Process Debt – e.g. due to missing workflows or the insufficient implementation of procedures
Are bugs technical debt?
Time and again there are discussions in organisations about whether bugs are technical debt. Yes, no, maybe? The answer depends on which interpretation you follow:
- Bugs are not deliberate. If you understand technical debt as a conscious decision for prioritisation in software development and thus follow the interpretation of Ward Cunningham, then the answer would be: no.
- If you understand bugs as a limitation of the functionality of a software, implemented by mediocre code and thus follow the interpretation of Steve McConnell and Martin Fowler, then the answer would be: yes.
And what is the answer if a developer believes that a bug will not be discovered and that he therefore does not need to fix it? Or if the development team decides not to fix a known bug? Possibly, the answer is then: maybe.
The challenge of eliminating code debt
How can code debt be eliminated? Of course, the first thing to do is to identify the specific debt and analyse ways to eliminate it. Often there are overlaps with architecture debts or design debts, so that a problem that seems small quickly becomes a big challenge. As a result, solution approaches have to be identified, efforts estimated, implementation prioritised together with stakeholders, appropriate staff allocated depending on the approach, and realisation scheduled. In other words, the elimination of code debt can be handled like a “normal requirement”. The real challenge in eliminating code debt, however, lies elsewhere.
In business practice, customers and users want new functions. The elimination of errors is a matter of course for them. Although they are well aware that software cannot be bug-free quasi by definition, if they have the choice between a new feature and the elimination of a problem, they will usually call for a new feature; especially if they themselves are not directly affected by the bug. It is similar with sales: they want to win new customers with new features. For them, too, the elimination of debts is a matter of course and even if they understand the sense and necessity of refactoring, a new customer is often more important to them than an existing customer and the (internal) quality of a software.
So the big challenge is to prioritise the elimination of code debts and thus the prioritisation of refactorings.
There are basically two options for scheduling and performing refactorings:
- In each iteration, effort and concrete tasks must be actively scheduled. If it is only a fixed value – e.g. 10 per cent of the total capacity – this period is often misused as a buffer for other tasks.
- An entire iteration or even an entire release is used for refactoring. However, this is difficult to communicate to customers, especially if they have the impression that the technical debt and the inadequate fix are literally self-inflicted by the manufacturer.
Ideally, organisations try to avoid pure refactoring iterations or releases. For many organisations, however, it is often the only option because the technical debt has assumed such proportions that meaningful further development of the product is no longer possible. Figuratively speaking, these organisations are paying compound interest for their prioritisation.
Impulses to discuss:
Technical debt should not be avoided, but must be managed.
Debt-free software development is not possible due to technical progress.
Technical debt is extinguished as soon as a product is no longer being developed – is this a flawed metaphor?
Since the amount of debt cannot be calculated exactly (and effort estimates are often inaccurate), the metaphor is “nice”, but only of limited use as a tool for software development.
How useful is it to consider the “cost of delay” when assessing “tech debt”?
 Market position as an aspect of a market goal
 History of Wikis
 The development of WyCash
 Ward Cunningham: Debt Metaphor
 Robert C. Martin: A Mess is not a Technical Debt
 Shaun McCormick: Why the way we look at technical debt is wrong
 Alistair Cockburn: Agile Software Development
 Steve McConnell: Managing Technical Debt
 Martin Fowler: Technical Debt und Technical Debt Quadrant
 Carnegie Mellon University, Software Engineering Institue: Towards an Ontology of Terms on Technical Debt
If code debt is a type of tech debt, then it is wrong to use it synonymously.
Here you will find additional information from the t2informatik Blog: