WorkServicesAboutInsightsCareers
Let’s talk

13 May, 2021;

9 min.

How to Deal with Technical Debt – a Guide for IT Leaders

One of the steps to manage technical debt is to properly define it. Let's take a look at the causes and types of technical debt, as well as strategies to prevent it and tips on dealing with it.

Marcin
Github LinkLinkedin Link
CTO
Matt
Linkedin Link
COO & Co-Founder
Bianka
Linkedin Link
Editor
Chapters in handbook:
  • See all →

More chapters are coming!

Notify me

Introduction

If you are wondering what is technical debt, and come to think whether it is something like financial debt, you’re right. The term is metaphorically associating software development with financial debt, where interest is extra work one has to do later on for coding quickly now. Though, the question for management isn’t the definition but rather how to deal with technical debt.

Still, defining technical debt is key and is one of the steps to manage it. Mostly, the concept of technical debt suggests the conscious trade-off between fast delivery and long-term effects, while some see it as simply the difference between results promised and delivered.

An example of technical debt dilemma would be a developer tasked with adding new features to a system and, thus, facing two ways:

  1. Faster and deficient.
  2. Proper but longer.

So basically, technical debt is the tasks you’re putting aside to finish the job. You are cutting corners in order to get back to it later and do it properly. It is an interim compromise.

Causes & types of technical debt

Though that’s a conscious debt, or an informed decision if you will, technical debt can also be created unknowingly or unintentionally. Leaving no annotations to the code, old and not addressed bugs or no automated test, as for example.

Typical causes for technical debt might be:

  • Poor (or no) upfront definition, when design and development starts without requirements set, to save time.
  • Deadlines/pressure that prioritize release over diligent completion of all tasks.
  • Lack of knowledge about technical debt, and thus making faulty decisions.
  • Lack of code documentation and/or testing procedures.
  • Poor technological leadership, poor collaboration between team members, lack of standards throughout the organization.
  • Delays in code refactoring, as often it has to be updated due to project evolution but is postponed for now, for tomorrow, for next week.
  • Budgetary issues/restrictions.
Typical causes for a technical debt.

In search of ways how to deal with technical debt, one could start by answering what type of technical debt is at hand. Because it isn’t only related to coding – it can happen at any development stage.

Bad code, and therefore tech debt, can be produced by skilled programmers who are under pressure. Many IT leaders stick to the 4-type classification of technical debt, proposed by Martin Fowler, a ThoughtWorks Chief Scientist and Tech Author. He stacks two categories together – reckless/prudent and deliberate/inadvertent, to describe all possible scenarios.

There’s also a simpler version, distinguishing 3 basic types – intentional (a deliberate decision), unintentional (outdated design, new features, etc.), and software entropy (deterioration of performance over time). While the first two of these aren’t too grave, you should, indeed, avoid the latter. You can also break technical debt into design debt, code debt, documentation debt, etc.

How to deal with technical debt

There is a number of processes and techniques to keep technical debt under control, including:

  • defining and tracking debt
  • prioritizing debt tasks
  • agile development approach
  • regular meetings of owners, managers, and engineers
  • setting coding standards
  • instituting code/design/test reviews
  • automated tests
  • code refactoring

Managing technical debt has two key aspects – preventing technical debt from accumulating – efforts to identify it, be aware of it and implement certain procedures, and repaying debt – prioritizing, incentivizing quality work, refactoring, etc. Thus, the concept is not all about restraining technical debt from incurring. Start with defining it.

#1 Preventing technical debt

Defining technical debt

The first step is the clear definition of and overall awareness about technical debt. In many cases, there is a different understanding by programmers and managers of what is technical debt. Often, debt, changes in code and adding new features are mixed up. Team meetings or training sessions to discuss technical debt, as well as to work out processes to manage it are good practice.

Train the collective ability to identify technical debt with signs like faulty code, overlapping technologies, bugs of various levels of threat. The definition of “done” should also be understood unanimously, if possible. Regardless is it a planned, unintentional or unavoidable technical debt you’re dealing with, everyone should grasp the consequences if it is abandoned.

There are 9 basic types of technical debt.

Tracking technical debt

As the team must return at some point to those put aside tasks, it is crucial not to delay it for too long. The time and resources you’ll have to spend for rework equal to the interest in financial debt. As technical debt has no clear metrics to track it experts recommend making a list of deferred tasks, inform everyone about it and schedule regular times to “pay it off”.

Agile development approach

Inherently close to tracking, there’s an argument for the Agile approach to help deal with technical debt. Agile environment, with frequent iterations of work, features, and bug fixes delivered, can be an alternative way to manage technical debt. Small chunks of work could help deal with debt in an ongoing manner.

It is sound, of course, to keep a backlog of deferred tasks. To repay technical debt though Agile approach, the definition of “done” and test automation might be helpful as well in the long run. Agile teams perceive job “done” as ready for release, which in regards to technical debt means strict supervision.

Regular meetings of owners, managers, and engineers

One other key thing in technical debt prevention – communication, cannot be omitted. Developers and managers should talk frankly and openly, especially in light of the fact that IT managers are also prone to mistakes. It is crucial to include deferred tasks in next sprints’ planning, not just in an issue tracker.

You also have to motivate staff to maintain quality work, or even reward it. Measuring the number of delivered features or bugs fixed is just an example of both motivation and tools to tackle technical debt. Such team culture will encourage code reviews, proper testing, mutual help and good practices.

#2 Repaying technical debt

Moving on to “repaying” aspect, it might be activities ranging from urgent temporary fixes to refactoring the whole structure of the code. Refactoring, actually, is one of the most frequently advised methods of how to deal with technical debt. At some point, it becomes inevitable, in fact, and we’ll get back to it in a moment.

Setting coding standards

Set procedures and schedules in motion in order not to let technical debt build up. Similar to financial debt, you have to plan pay-off periods to reduce the debt, which means scheduled days or hours when the team is doing the clean-up. A popular practice is doing it piece-by-piece, instead of trying to rid the whole debt at once.

Bottom line: plan, predict, pay.

Instituting code/design/test reviews

Another technique for technical debt is testing and code reviews. As critical as testing for the software development process, is a culture of code reviews. No matter how much and how rigorous testing you conduct, an independent fresh look can help spot missed typos, bugs, edge cases, etc.

Effective strategy for dealing with a technical debt includes assessment, communication and implementation.

Automated tests

An integral part here is automated tests. 99% of engineers agree this is the best way to avoid bugs. In essence, automated testing is a bunch of individual tests – as automated scripts, to double-check the code and validate the system in entirety.

Apropos, one of the universal rules is making legacy code understandable because you’ll get legacy code no matter what. Organized, clean and apprehendable code will not leave new developers baffled when they get to it months or years later. As “to-do” is sort of programmers’ inside joke, and different developers have different coding styles, a source control system could be a handy artifact, providing a history of changes and explanations.

And naturally, in some cases, there is no need to repay technical debt. It is simply not worth the effort when debt is related to prototypes, experimental projects, systems approaching termination, or migration from a legacy system to a new one.

Refactoring

Adding few lines of code here or there to fix a bug or to add a new unplanned feature is a common thing. It then accumulates, your codebase becomes messy and, eventually, you’ll just have to restructure the code to make it orderly.

This is called refactoring, and you’ve probably seen it many times in relation to technical debt. In fact, as soon as the project has been designed and launched, refactoring becomes the only way to reduce technical debt. It can speed things up, though as in any sizeable code there is always a place and reason for refactoring, the key is to do it in the right places.

Often both project managers and developers are reluctant to code refactoring, because, in their words, it doesn’t fix bugs, it is too risky and takes time, or the existing code works fine. So, before doing it, you better get everyone “on the same page” about it. When all recognize the value of refactoring, as well as acknowledge the technical debt, there’s a chance of positive outcome.

Few tips:

  • Welcome regular minor refactoring to implement best practice design patterns,
  • When a code is easy to read (names describe the purpose), refactoring may be simply renaming classes/methods/variables or re-organizing them,
  • Encourage engineers who have a “better way” ideas,
  • Don’t do it prematurely – not all refactoring have to be done before the v1.0 is released,
  • Branching the codebase, as a kind of refactor, might be helpful in some cases – consider assigning some time to developers for it.

Wrapping up

Technical debt isn’t necessarily a bad thing, it just has to be a conscious decision. With financial debt, to manage it you lessen interest payments – the same goes for technical debt. Remember to focus on three aspects: people, technology, and processes.

Facilitate awareness and accountability about technical debt among team members. Backlog any incomplete or deferred tasks, regardless of type, significance or development stage – the prioritize and complete them. Use tools for visibility and control over technical debt.