Software development is a very dynamic industry. New features, functionalities shall be deployed fast. While the resources are often limited. Writing code and covering it in tests requires more time and money than just writing code. Developing a basic functionality that will not scale in the future is cheaper and incomparably faster than developing a fully-fledged solution that will scale with the business growth.

So why not skip testing and QA? It will speed up the development process. Why not choose a basic solution over a proper one? It will cut costs significantly, not to mention the time needed to get a ready product.

That’s why companies choose a faster and simpler solution over a more reliable one. And it leads to the accumulation of technical debt.

What is technical debt? 

With time, software tends to accumulate cruft. Those are deficiencies in the software quality that make it difficult and costly to extend or modify the software in the future. Why do we use the word "debt" though? We can compare software technical debt to a financial one. You repay it not just with the sum borrowed but with interests. When you need to extend the system, you need to make an extra effort to implement the extra features. This extra effort is the interest you pay for the technical debt.

With time, this cruft accumulates. Therefore, it takes extra effort whenever you need to implement a new feature.

For example, we need to implement a feature. If the system is developed properly, the new feature implementation takes approx. two days. But if the system has accumulated technical debt, we add the time and effort needed to implement the feature to the time and effort needed to handle the accumulated cruft. Say, the entire process will take 5 days instead of two. So, three days are the "interests" paid for the technical debt. 

At some point, it will be easier and cheaper to develop a new solution instead of sustaining the old one.

Image.

Types of technical debt

Why do teams accumulate technical debt? It happens because of different reasons, both inside and outside of the team. Depending on the reasons, we can classify technical debt into the following types. 

Deliberate technical debt

Deliberate technical debt is created deliberately. You might be wondering why one would ever do it? It can be done for many reasons. 

Let’s compare it with a shelter. If one doesn’t have accommodation, even a tent would work as a shelter to protect from wind and cold. If a company needs a solution urgently, it might request something that works right now even if it is not reliable in the long run. Further, when a tent is already available, a proper home can be built. The same with software. Once an emergency solution is available to keep the business running, a proper product can be built. So, the team builds a "tent" deliberately knowing that later, they will need to build a proper solution. 

When a new feature shall be implemented asap, the team also might understand that they are accumulating technical debt by prioritizing the development speed. This is also deliberate technical debt.

If this is the case, developers write a lot of in-code documentation. Its aim is to explain the poor quality of the code. It also explains the right way to code and gives information needed in the future to fix the code. 

Why documentation and not tickets? The thing is that the project might be passed to a different team without the ticket history. So, even if tickets are created and maintained properly, they will be useless. While in-code documentation will explain the situation and inform about the possible fixes.  

Is there a reckless deliberate technical debt? Of course, there is. When the team sees that they don’t have time for testing, or QA, or a proper design of the product, they might skip the procedures. But the team isn’t going to deal with the consequences. They just deliver the product “as is”, with the hope that it will function somehow, and the client will accept it.

Image.

Inadvertent technical debt

This is technical debt that was not the result of planning, it was not accumulated deliberately. It can be accumulated for several reasons. 

When we write code, we learn. Moreover, we learn when we are working on a non-standard complex solution. 

It happens that we complete the product, it is pushed to production, the client is happy, users are enjoying using the solution. But we realize now, when everything is finalized, that some things could have been done differently. It is also technical debt. But we have learned from it. And when we work on a similar functionality the next time, we will handle it better. So, here, we deal with inadvertent prudent technical debt

But it happens that sometimes, a client has to deal with a team's incompetence. When a team doesn’t handle a product properly just because they are incompetent or ignorant, we can speak about the accumulation of inadvertent reckless technical debt.

Human cost of technical debt

For every team member, technical debt is a burden. It makes the team unhappy, and an unhappy team is less productive. 

For a project manager, technical debt means much slower feature delivery. 

For a developer, it means being unproductive from day to day. It happens because the simplest action such as adding a checkbox requires more effort. And developers have to explain why easy tasks take a lot of time. It is similar to being harassed by creditors all the time, and it is pretty demoralizing.

Technical Debt

Team members start blaming each other which adds to the frustration and embarrassment. 

As the frustration grows, team members might feel that their professional relevance is slipping away. The accumulated technical debt creates not only significant delays with feature releases but influences the general codebase evolution negatively. 

With time, everything becomes difficult. Team resists incorporating new design and architecture practices. The implementation of new features is postponed. All in all, they would not touch anything because every change makes the problems grow like a snowball.

Business cost of technical debt

Technical debt impacts negatively not only the team. It has a direct impact on the product, and thus, on all the business processes. 

New features cannot be added, architecture cannot be improved, and the product stops responding to the market demands. The product scalability tends toward zero. Your business starts losing the audience. The profit stops increasing. 

Now, you get why managing technical debt is crucial for both the team and the business.

How do we manage technical debt?

Technical debt management depends greatly on the technical debt type. So, deliberate prudent technical debt is easier to manage because the team has planned it and is ready to deal with it. The management of reckless technical debt is much more complicated. 

So, how can you avoid the accumulation of technical debt? The solution is proper technical debt management. It starts with the proper explanation to your client what technical debt is and why it is better and cheaper to eliminate it before moving on with additional features. Such an explanation is needed if you have to deal with inadvertent technical debt. 

At Mad Devs, we frequently work with projects that were initiated by other teams. So, we often have to deal with the accumulated technical debt. 

We explain to the client that the implementation of every new feature will take much more time if we don’t deal with technical debt. The possibility of bugs and errors in the future increases, too. If technical debt isn’t managed, in the future, it will come to the point when it is easier to write a new solution from scratch than struggling with the accumulated technical debt.

Further, we act according to the plan:

  • We document technical debt. We create tickets, add them to epic, add the ticket description in code.
  • We write tests. Only when the code is covered in tests, we can start working with technical debt. What if tests are absent? It is the right way to more bugs and a heavier technical debt. 
  • Finally, we close technical debt. We perform code refactoring, libraries updates, we add interfaces, modify the project architecture, implement new tools (e.g. Redis), and similar.
Image.

Action plan on technical debt management

We always have a clear plan on how to manage the accumulated debt. We create a plan to make it clear for both the team and the customer about what part of technical debt is going to be solved.

Here is how we act to determine the volume of the accumulated technical debt:

  • We analyze the code base and other project parts to check whether there are any issues.
  • We make a list of issues.
  • We analyze the roadmap to see what technical debt needs to be solved to implement the needed features faster and make the product more scalable.
  • We edit the roadmap if needed.
  • We agree with the client on the needed fixes.
  • We resolve the technical debt and implement the needed features.

If the project has accumulated technical debt, around 20-30% of tasks in every sprint are devoted to technical debt management.

Technical debt management in Jira

We use Jira to visualize the technical debt volume and track the progress on the technical debt resolution.  

Here is how we organize and solve the tasks:

  • We create an epic called Technical Debt.
  • We create tasks.
  • We link the epic to Analytics and Comedian.

So, we can see clearly what tasks are left, how much time they might take, and the progress on them.

We demonstrate to the client that the work has been done

We are not just working on technical debt resolution. We demonstrate to the client what has been done. If the client doesn’t have a technical background, it might be difficult. That’s why we combine several methods to show what has been done to fix the technical debt:

  • The text coverage – the more code is covered in tests, the lower is the possibility of bugs and errors. We aim to cover 100% of the code in tests.
  • Metrics showing the website speed – if the website started loading faster, it is clear that some issues were solved.
  • Users’ complaints about the errors – if their frequency level drops, it means that some fixes were made.
  • The number of code lines became lower – a bulky code is bad code. Everything shall be transparent. We make code clear and transparent by reducing the number of code lines.
  • Changes in the architecture – we show how it was and how it became.
  • Cycle time – when the time needed to deploy a new feature decreases, it means that technical debt has reduced.
  • Stability growth – when implementing a new feature requires less changes in the other system parts.
  • Or we might use any other technical debt metrics. 

We provide information about technical debt in connection with a business. So, we would not say that we need to refactor a code. We would rather say that the majority of failures are connected with a low-quality code here. If we improve the code, users will use the product more willingly, and its ROI will increase. Such an approach allows our clients to understand better why technical debt management is important.

Image.

Bottom line

Mad Devs’ engineers never leave the project "as it is." Even if the previous team has accumulated heavy technical debt, we manage it by prioritizing tasks correctly. Technical debt management doesn’t mean that the work on new features won’t move on. For us, it means that along with the implementation of new features, we are fixing the accumulated issues.

Explore the chapters