Technical Debt: from a nightmare to an old memory

Sylvain Tiset
6 min readMay 2, 2024

--

Technical debt is a nightmare for software development. What is it and how can we deal with it ?

Technical debt, a nightmare for software development generated by Microsoft Bing AI

What is technical debt?

Technical Debt is everything that stops us from developing software fast.

The following picture illustrates perfectly the problem of developing fast over time.

Over time, the capacity to develop new features decreases from this article

Types of technical debt

The well-known software development expert Martin Fowler, has described four types of code debt. He invented the technical debt quadrant to classify these types of technical debt.

Technical Debt Quadrants from Martin Fowler and this article
  • Reckless & Deliberate: came from intentional decisions made with full awareness of potential bad consequences. Good practices are ignored to ship product faster. This often comes with short deadlines and management pressure
  • Reckless & Inadvertent Debt: developers unintentionally introduce technical debt due to a lack of knowledge, skills, or experience
  • Prudent & Inadvertent Debt: the dev team applies best practices but still generates technical debt by failing to make the codebase evolve. As the future is unpredictable, this type of debt is inevitable. Still, it can be manageable if the team refactors, updates, or migrates their code regularly.
  • Prudent & Deliberate Debt: the dev team agrees to introduce some technical debt as it is seen as a trade-off to deliver value faster. This type of debt can be beneficial, as it can help developers learn, experiment, or validate their assumptions. The aim is still to pay off the debt as soon as possible

What are the causes of technical debt?

  • No code quality: the code is not clear, there are no coding standards, comments explaining what the code does. There is a lot of complexity like high coupling between classes or modules
  • No tests: there are no (or not much) unit tests, nor integration tests nor end to end tests in the project
  • Unclear project requirements: when requirements are not clear, the team can be forced to go back into the code and rework to include new components that conform to the new requirements
  • Outdated libraries: having a project with outdated libraries or worse, outdated language version can lead to big security issues and the unability to update the code to the new versions
  • Manual Devops process: there are no automated builds, no CI/CD process
  • Wrong architecture: no logic project architecture, the system doesn’t scale well
  • Lack of documentation: there is no documentation explaining the system’s state
  • Lack of knowledge sharing: no sharing knowledge culture, hard for newcomers to improve skills on the project
  • No training: a lack of developer training can lead to poorly written code

Technical debt consequences

Technical debt can lead to multiple issues in the software development. Let’s talk about the main ones:

Code

  • Complexity: increasing complexity creates more technical debt
  • Bugs: bugs directly impact the product
  • Code quality: reduced code quality impacts the time to deliver new features

Product

  • Functionality: features fail to work correctly, impacting usability and customer satisfaction
  • Delivery: late deliveries can impact customer trust
  • Downtime: has a direct impact on the brand reputation
  • Risks: increase security issues

Team

  • Slower development speed: dev team has to work on the technical debt instead of developing new features
  • Team morale: no one likes to work with legacy code
  • Retention: unhappy developers are more likely to resign

Business

  • Customer satisfaction: there is a always direct link between technical debt and customer satisfaction
  • Business efficiency: difficult to predict milestones correctly
  • Brand and reputation: on the worse case, once the brand reputation is dammaged, it is difficult to gain customer trust back
  • Finances: development costs that leads to down revenue
  • Survival: bankruptcy in the worst scenario

Everything is summing up in the following schema:

Impact of technical debt from this article

How to measure technical debt?

There is no measurement of technical debt. However, there are some tools that can give a good idea of how the code is badly written.

  • SonarQube has a quality gate metric that qualifies your code against code smells, debts, vulnerabilities, and bugs
  • Coverity helps identify resource leaks, memory, corruptions, error handling issues, and more

Another way to have an indicator of technical debt is to calculate the Technical Debt Ratio (TDR).

Technical debt metrics needed to take into account while calculating the ratio:

  • Development cost calculated in hours (time taken to develop a feature/product)
  • Lines of code (LOC) (the total number of code lines)
  • Cost per line (CPL) in hours (time to write a line of code)
  • Remediation cost in hours (time to make a repair)

The formula for calculating the technical debt ratio is the following:

Development cost = Cost per line (CPL) X Lines of code (LOC)
Technical debt ratio = (Remediation Cost / Development Cost) X 100

A value under 5% can be considered as fine in a project.

Dealing with technical debt

The first thing is to “measure” technical debt using tools like SonarQube or calculating the TBR, like it is described in the previous section.

Once we have a clear view of what should be done, we can put a strategy in place to tackle the technical debt.

The following strategy is simply based on benefits over complexity.

  • High benefit & low complexity: do it immediatly
  • High benefit & high complexity: plan it
  • Low benefit & low complexity: consider to do it when there is an opportunity
  • Low benefit & high comlexity: to be done when all the rest has been already tackled
Strategy to tackle technical debt by this article

Another practical approach is to include technical debt in the sprints. The best way is to empower teams to fix problems and resolve technical debt in the natural flow of product development by a ratio of 10% to 20% of the sprint time. Here is how it can be distributed:

  • For smaller debts (up to a few hours), do a refactoring when you touch them. But, then, let people be Good Boy Scouts.
  • For medium debt (from a day to a few days of work), you can try the following: Tech Debt Fridays are working only on this, or mark tech debt as a feature, prioritize it, and work on it.
  • For more significant debt (from a few weeks to a few months), take fixed time for tech debt. For example, take a story and work two days on it, or have a special task force (dedicated team) handle it for some time.

Best practices

No time for improvements from net solutions
  • Follow coding standards and good practices, to have a cleaner code base and write high quality code. This includes OO concepts, design patterns, refactoring, clean code principles, architecture patterns and styles, and SOLID, YAGNI, KISS, and DRY principles
  • Add Continuous Delivery to save time and avoid production issues
  • Write tests to have ideally 80% of code coverage, ideally using TDD methodology
  • Code reviews: add code reviews if there is not in the project, encourage a deeper code review culture if it exists (see 7 ways to improve your code review)
  • Pair programming: will short the feedback loop of the code review and will propagate the codebase knowledge to team members
  • Refactoring should not be asked for permission, especially if it’s something that can be done in a few hours
  • Organize “tech debt workshops” to build a map to tackle the debt (typically using the map shown in the previous section)
  • Involve architect (or tech lead) to have a clear view of what could be done, and how the code should be structured or reorganized
  • Write documentation to reflect architectural decisions

Thanks for reading this article. What do you do to identify your technical debt? Are you using other methods to tackle it? Feel free to give your answers in the comments.

--

--