In the most general sense, software technical debt refers to the “cost” of maintaining and updating software due to insufficient planning, lack of design, or developers implementing “shortcuts” during the development process. This widely adopted definition results in a backlog full of items depicting the necessary improvements which can be translated to cost (whether it is in man hours, productivity loss or other types of monetization).
Note that the term shortcut is used here to describe low-quality code or actual poor software implementation (i.e., incorrect algorithms, wrong integrations, misconfiguration or other poor technical decisions), which can lead to difficulties in making future changes or cause inefficiencies and even defects in the long run.
Common types of technical debt
Technical debt can be grouped into 5 broad categories:
- Architectural debt
- Code debt
- Process debt
- Decision debt
- Security debt
It’s not uncommon for these categories to be further extended or even changed depending on the characteristics of the software project, for example to cope with the type of application, its criticality within a particular industry, platforms in scope, development process used and even the roles involved.
The following descriptions give a better understanding of each tech debt type along with an example of the types of quality software issues that can be related to each type:
Inconsistencies in the software design and architecture leading to problems in scalability and maintainability or other non-functional requirements. This type of debt can lead for example to design flaws and system-level defects, performance bottlenecks, scalability and incompatibility issues which can be awfully time consuming to fix.
Poor quality of code, lack of documentation, and lack of unit testing that leads to difficulties in understanding and maintaining/enhancing the code. Code debt can result in implementation defects, poor performance, brittle functionality, inability to perform updates on software dependencies or underlying hardware upgrades and create security vulnerabilities.
Inefficient development processes, such as inadequate definition of required functionality, lack of code reviews, ineffective or insufficient testing can lead to unimplemented requirements, duplicated or wasted development efforts and lack of overall quality in the released software product (i.e., introducing bugs and security vulnerabilities).
implementing quick fixes rather than long-term solutions, or insufficient research or analysis of a requirement or issue can lead to long-term maintenance and support issues related to poor design choices or inadequate risk management.
Neglect of security considerations, such as failure to implement proper security protocols, updated libraries, inadequate configurations or re-inventing the wheel instead of using proven solutions can lead to a bigger attack surface for cyber-attacks (i.e., due to lack of proper authentication and authorization controls or unpatched vulnerabilities).
But that’s not it!
One can immediately appreciate that the proper and timely identification of technical debt might be the difference between a successful or a doomed project, but capturing all this debt of different types might seem challenging and cumbersome even for a mature team (i.e., with high seniority members and that has been working together for a fair period of time).
In 2020, Luca Rossi reflects on a blog post on the comments of Ward Cunningham (original inventor of the term Technical Debt) about how technical debt is not really related to “dirty” or “bad” code but to the lack of compliance to (implicit and explicit) business requirements. He also proposes 2 reasons this comes to happen, and how to deal with them in a “healthy” way.
As all common types of technical debt can be mapped to software defects and following the line of thoughts from Rossi and Ward, in the next post I’ll introduce the concept of Quality Debt.