# Technical Debt

## Summary


To write good software, developers have to follow best practices: architecture, design patterns, code structure, naming convention, coding guidelines, test coverage, documentation, etc. In practice, business needs may push developers to release a functioning product as quickly as possible. Developers may violate the best practices, hoping to make improvements at a later time. When this happens we have **technical debt**. 

The goal is not to eliminate technical debt. We accept technical debt in the short term and manage it in the long term. If it's ignored, problems will accumulate until demoralized developers, missed deadlines, unhappy customers and increasing costs drive the product out of the market. 

The problems indicated by technical debt are related to many other terms: software maintenance, software evolution, software aging, code decay, code reengineering, design smells, code refactoring, deficit programming, and technical inflation.

## Discussion

### Why do we call technical debt a "debt"?

The debt metaphor comes from finance. It's common for companies to borrow money to grow faster and capture the market quickly. However, this debt has to be eventually repaid with interest. The longer the company delays the repayment, the more it pays in terms of interest. Ward Cunningham applied this debt metaphor to technology, more specifically to software development. 

Due to various reasons, developers might not adopt the best approach to build their product. They might release the product even when they don't understand some parts of it. This is the debt they acquire in the hope that they will fix these issues in a future release. Bad code and poor understanding of that code lead to more time and effort to add new features. This is the interest paid on the debt. An hour saved today would require more than an hour tomorrow to fix the problem. 

Code refactoring leads to better design that's easy to understand and maintain. However, the longer they postpone this refactoring, the more difficult it becomes to refactor, just as interest payments continue to grow in financial debt. 


### What's principal and interest with respect to technical debt?

In finance, when we borrow money, the principal has to be paid along with interest. The longer we delay the payment of principal, the more interest we pay.

In technical debt, suppose we keep working with poor code, design or documentation. **Interest** is the extra effort we pay to maintain the software. As the software gets more complex with each release, interest keeps going up. 

Instead, we could refactor the code incrementally and make it better for future maintenance. **Principal** is therefore the cost of refactoring. Paying the principal today reduces future interest payments (extra effort). 


### How does technical debt arise in a project?

Technical debt could arise due to "business pressure, incorrect design decisions, postponing refactoring indefinitely, updating dependencies or simply the lack of experience of the developer". Bad practices can lead to technical debt: starting development without proper design, lack of testing, poor documentation, or poor collaboration. 

A software product may start with a clean design but incur technical debt as requirements change. Sometimes a software component could undergo a number of incremental changes made by multiple developers. These developers may not fully understand that component or its original purpose. Some call this "bit rot technical debt". Coding by copy-paste is a symptom. 

Sometimes a third-party software is upgraded in an incompatible manner, such as Magento 1.x to 2.0. All websites using Magento 1.x now have a technical debt since there's no simple upgrade path. 

Consider a web application. Though Ajax might be the right approach, it would take longer to develop. So developers use frames instead. This is a conscious decision that incurs technical debt. Developers must still implement a clean solution that can be migrated to Ajax easily in a future release. 


### What are the different types of technical debt?

Back in 2009, Martin Fowler identified four types of technical debt: 

    + **Reckless & Deliberate**: Developers are aware of good design practices but deliberately choose to ignore them and produce messy code. This leads to excessive interest payments and long time to payback the principal.
    + **Reckless & Inadvertent**: Developers are clueless about good design practices and produce messy code.
    + **Prudent & Deliberate**: Developers willing incur debt because they estimate that interest payments are small (rarely touched code). They do a cost-benefit analysis and accept the debt if it can be overcome.
    + **Prudent & Inadvertent**: This is often retrospective in nature. Developers release clean code but later realize that they could have done it differently. This is inadvertent debt. Developers are constantly learning and trying to improve their code. As systems evolve and requirements change, developers may find better designs.From the perspective of interest payment, we could classify technical debt as **eventually repaid** (refactoring on a daily basis, debt tends to zero), **sustainable** (refactoring regularly, debt is constant) or **compound growth** (adding new features but not refactoring, exponential growth of debt). 


### Could you share some case studies of technical debt?

According to a study by Stripe, developers spend nearly half their time fighting with technical debt. They estimated that this amounts to $85 billion in annual cost. 

Another study of large software organizations showed that 25% of development time is the cost of technical debt. Only some used backlogs and static analyzers to manage technical debt. Very few had a systematic process for addressing technical debt. 

Twitter's platform was built on Ruby on Rails that was hard to optimize for search performance. Twitter solved this by eventually switching to a Java server, thus paying off its technical debt. 

A Canadian company successfully released a product locally. When they expanded to the rest of Canada, they had to cater to 20% of French-speaking Canadians. They quickly solved this by using a global flag and lots of if-else statements in code. Later they got an order from Japan. Had they made their software multilingual earlier, they could have easily updated their software for Japanese or any other language. 


### What are the consequences of technical debt?

If not managed, technical debt has long term effects on the product. It becomes difficult to add features or improve the product. More time is spent on paying off the interest. Any change implies higher costs. As product quality deteriorates, system outages or security breaches can lead to lost sales or fines. The cost of a quick release might be poor design, more bugs, volatile performance, and insufficient testing. 

Technical debt has a human cost too. Developers become unhappy. Adding new features becomes a pain. Even when new developers are hired, it takes time to explain what the code does or why it's so messy. New developers could start blaming older developers for the technical debt. Teamwork suffers. 

Crippling technical debt might force the team to postpone big changes. They might not adopt latest technologies or upgrade to the latest versions of third-party libraries. Developers might get stuck with outdated frameworks and have no opportunity to upgrade their skills. They may even leave for better opportunities elsewhere. 

Ultimately, these problems can be related to business risk, cost, sales, and employee retention. Technical debt gives developers a language to communicate clearly with business folks. 


### How can I manage technical debt within my project?

Technical debt when addressed early requires only some code refactoring. If this is postponed, a more expensive rewrite may be needed. 

As in financial debt, it's better to pay off the principal to save on future interest payments. In other words, developers must **continuously refactor code**. If a new feature takes three days, a developer could take an extra day to refactor. This might simplify the current feature and make the code easier to work with for the future. 

Once code is shipped to customers, developers are reluctant to change it, for the fear of breaking system behaviour. The solution is to add **more tests**. In fact, technical debt implies a more disciplined approach towards refactoring and testing. 

Developers should follow **good design practices**: reuse rather than duplicate code; design highly cohesive and loosely coupled modules; name variable, classes and methods to reveal intention; document the code; organize code reviews. 

Unlike bugs, technical debt is often invisible. **Tools** such as *Designite* can help identify and track debt. Prioritize high-interest debts for refactoring. Motivate and reward developers for refactoring. 

## Milestones

1992

Ward Cunningham coins the term **Technical Debt** while working on WyCASH+, a financial software written in Smalltalk and employing object-oriented programming. He notes that it's important to revise and rewrite code towards better understanding. He also notes,

> 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.

2001

**The Agile Manifesto** is signed. In the following years, as the Agile software movement gains adoption, it also brings more visibility to technical debt. Technical debt becomes an essential concept of software engineering. Agile is about faster development and responding quickly to customer needs. This focus on short-term deliveries should not compromise long-term goals. It's in this context that technical debt becomes relevant in Agile. 

Sep  
2009

Robert C. Martin (commonly called Uncle Bob) makes the point that technical debt is incurred due to real-world constraints. It's risky but could be beneficial. It requires discipline and clean coding. **Messy code** is not technical debt. Messy code is due to laziness and unprofessionalism. 

Oct  
2009

Martin Fowler expands on Uncle Bob's explanation of technical debt. In the process, he identifies the **four quadrants** of technical debt. He also notes that technical debt is a useful metaphor when communicating with non-technical people. 

2016

At the IEEE 8th International Workshop on Managing Technical Debt, researchers present their findings on **technical debt in embedded systems**. They find that test, architecture and code debts are more common. In embedded systems, runtime aspects are prioritized higher than design aspects. When the expected lifetime of a component is more than ten years, its maintainability is more seriously considered.