Technical debt - how to build future-proof digital products?

Today, many software companies are feeling the pressure of the market, constant competition, and the need to meet ever-increasing customer expectations to proliferate and deliver better and more advanced products. The resulting need for constant and vigorous evolution means that many product and software development teams must face the problem of technical debt. How to deal with it?

What is technical debt?

Ward Cunningham, an internationally known and well-respected software developer, has contributed to corporate IT by defining the term ‘technology debt’. With its introduction in 1992, the view of the hidden costs of future work has changed - i.e., all those things that do not arise directly from the tasks at hand but are necessary to be done on occasion or before we can get down to the actual work.

The technical debt definition (also known as tech debt or code debt) states what happens when development teams focus on quickly delivering a set of features or a design that later needs refactoring. Simply put, technical debt is either the result of prioritizing speed of delivery over quality and functionality, or more commonly, the effect of dropping the development or support for a particular platform.

However, it should be remembered that technical debt defined in this way encompasses several activities that can distance us from the realization of the acquired goal - from the choice of technology, through the proper configuration of the development environment, to the division of responsibilities. Technical debt is therefore incurred in a situation where we quickly perform work of a specific scope without careful consideration of scalability, increasing the risk that we will later spend more time improving the work done so far.

It is interesting to note how, years later, Cunningham recalled the emergence of the concept of technical debt in his mind:

“With borrowed money, you can do something sooner than you might otherwise, but then until you pay back that money, you’ll be paying interest. I thought borrowing money was a good idea; I thought that rushing software out the door to get some experience with it was a good idea, but that, of course, you would eventually go back. As you learned things about that software, you would repay that loan by refactoring the program to reflect your experience as you acquired it.

What are the main causes of technical debt in digital products?

If you’re managing a department or team, you can obviously take some actions to avoid technical debt in your products. But it’s good to understand what causes it in the first place. Knowing that might be helpful in preventing the same situation from occurring again. Usually, the key sources of technical debt are:

  • low quality of the code itself,
  • very often it comes with low development skills in the team or department,
  • lack of testing, or low testing standards,
  • unrealistic timelines and pressure on the development team,
  • overengineering and excessively complex implementations,
  • ineffective methodologies or frameworks (e.g. waterfall, with its tons of documentation and inflexible approach to goals),
  • focusing only on one specific aspect of the digital product (for example, creating a website without a holistic approach, without UX/UI or SEO elements),
  • using a temporary solution as the final product (e.g. using an MVP long-term),
  • pressure from stakeholders to focus on one aspect of the product, for example on visuals, apart from SEO, UX, performance or security,
  • poor leadership, lack of experienced mentors and micromanagement.

And the key reason that can sum up all of those mentioned above: too great a focus on delivery, instead of focusing on better understanding the products’ business goals. However, technical debt is not always a bad or unconscious choice.

Is technical debt bad or good?

It all depends on the context and project needs. In some cases, like developing an MVP app, technical debt is something that is … chosen deliberately. Minimum Viable Products are created when there’s a need to balance business needs, quality, functionality and the pace at which the software is delivered.

This means that you can consciously choose to create technical debt, because MVPs are only suitable as tools to validate business hypotheses. In other words: you can agree on making an app that will lack a degree of quality, in order to deliver it faster and test your business hypothesis. After validating the hypotheses (positively or negatively), you can either ditch the app and create a new one, or improve the existing MVP, if this is what was planned.

However, if you’re planning to scale your product, to enter a new market for example, technical debt is something you definitely should avoid. A fundamental issue in this context is the choice of infrastructure and turning to scalable solutions, allowing the future to easily develop the product and its architecture and ensure seamless maintenance. Most importantly, lack of technical debt is one of the factors that keeps users satisfied.

However, regardless of all the mentioned examples, technical debt is a clear signal for a software development company and DevOps teams that something must have happened that influenced the decision to implement a solution that differs from the ideal. In the case of technical debt, we are dealing with a snowball effect. A process that starts on a small scale (in an MVP or first version of the app) then gradually grows. An essential aspect of the result is that the more advanced the process is, the harder it is to stop.

Consequences of technical debt

One of the biggest consequences of technical debt is that … it’s unavoidable. Especially if you want to keep your app or digital platform profitable and user-friendly.

There are opinions suggesting that test-driven development (TDD) helps to avoid technical debt in a systematic way. However, it’s more a method for keeping the code in a healthy state, rather than avoiding debt in general, as technical debt itself is not only about the quality of the code.

As mentioned, the snowball effect takes place here. If your development team says that fixing something, starting from today, will take two months, it means that in six months’ time, to fix it will take three months instead. So, what are the results of focusing on adding new features, instead of paying the debt?

Malfunctions, bugs, poor performance, data leaks and other security issues are at the top of a very long list of possible issues. This can, and eventually will, lead directly to:

  • Decreasing sales (if the product is related to sales of services or products), customer satisfaction and other, vital KPIs.
  • If the development team is aware of the technical debt but doesn’t have resources to fix it, it will lead to growing frustration and decreasing morale.
  • Overwriting or looking for new “creative” ways of avoiding old code makes the development process more complicated and increases the time needed to develop a feature.
  • Steady and interrupted growth of technical debt can lead to a situation when the development can’t be continued any further. This is, arguably, the most harmful consequence of untreated technical debt. Especially if stakeholders are not technically savvy enough to understand how important it is to deal with the debt.

In this case, it’s not a matter of “if”, but rather “when” the debt will start harming your business. It’s important to start dealing with technical debt, before it becomes a very real and disastrous avalanche of problems.

So how can we effectively deal with technical debt?

If your product or service is already suffering from technical debt, there’s still a couple of things you can do to improve the situation and prevent such issues in the future.

  • The very first one is to realize that technical debt takes place, and define what it means for your product. A code audit will be extremely helpful to map all the existing and potential issues. Ideally, such an audit should be conducted by someone who is not involved in the development process. Combining it with a UX/UI audit would be an even better solution.
  • The team should adopt clear coding standards and agree to respect them. While this sounds quite straightforward, it means that sometimes you will have to review the skills of your team (or your external partner’s team) and either strengthen them, or look for help from outside.
  • When coding standards are in place, make sure that quality is satisfactory. A quality assurance engineer (QA or QA/BA) with a focus on the product to review coding standards and automated tests is crucial here.
  • In addition to adapting your code to the standards already in place, you also need to pay attention to the team’s pressures. So, if you notice a drop in productivity and motivation in your team, postponement of implementation, or an increase in the number of bugs, take action.
  • Don’t cut corners or… cut them very wisely. Shortcuts in development run the risk of creating technical debt and failing to deliver on initial assumptions. However, if you have to compromise on something, make sure you can go back and solve it later, before it starts causing problems.
  • Implement an agile approach to the team, for example by using a scrum or kanban framework. This move can give a lot of freedom, but also responsibility when it comes to choosing what the team will work on in the next sprint.
  • It is also a good idea to reduce the business requirements per iteration or to prioritize tasks differently, making sure that the technical debt is “paid” regularly, even with small improvements.
  • Make sure that you have support from the whole development team. That will ensure that potential improvements and new iterations avoid technical debt.
  • Thoughtful product scaling significantly reduces the occurrence of technical debt and lowers the costs associated with it for the entire organization.
  • One of the biggest challenges is to persuade stakeholders that tackling technical debt brings many benefits to the digital product. While it often doesn’t bring any visible benefits (like new features) from the user perspective, it surely helps to keep them satisfied with the way the application works, and prevents future problems.

Technical debt - a silent threat

Technical debt is like any other kind of a disorder. It arises by itself, and the longer it remains untouched, the more resources it takes to eliminate it. Thus, the good advice I want to share with you today is to take care of it as soon as possible. Ideally, in a systematic and thoughtful way.