What is technical debt? In a nutshell, technical debt is unnecessary complexity in code. Not to be confused with the essential complexity imposed by business requirements.
Unnecessary complexity makes every new feature and every change a little harder to develop than it needs to be. The higher the unnecessary complexity, the harder it is to understand the code, estimate the effect of changes, and test the code. All this slows down further development.
“We have no technical debt or legacy code”
Unnecessary complexity almost always appears in a software system. Whether it’s through ignorance, the deliberate acceptance of ‘bad code’ to deliver features quickly, too many unnecessary features, etc.
Additionally, software is part of a constantly changing environment. New technologies emerge. Management changes and old paradigms no longer apply. Requirements change and some of the features are no longer needed. The list could be extended endlessly.
Even if you did everything right from start to finish, the changes in the environment create technical debt. Any code base degrades over time.
“We must eliminate all technical debt”
The statement is of course an exaggeration. However, the tendency to do so can be found everywhere. Hence the question: Does technical debt always have to be completely removed?
If you take a closer look, not all technical debt is equal. The difference lies in its impact on the daily work of developers.
Technical debt that constantly hinders the team, makes things permanently complicated, leads to errors over and over again, has a completely different status than that which is neither read nor touched. Reality, of course, lies between the extremes. Nevertheless, teams are usually good at assessing what is really hindering them at the moment and all the rest.
But what’s so bad about always wanting to eliminate any technical debt you encounter?
There are several reasons for this:
Software development is not an end in itself. Our goal is to create value for our users and - in most cases - to earn money with a product or service. In other words, the balance between cost and benefit must be maintained also for technical debt.
It’s unclear what’s next. As software developers, we work in an environment of extreme uncertainty. Requirements change, a new technology emerges, and so on. So it’s unclear whether the next time the code is edited, today’s changes are still appropriate.
Inherent and unnecessary complexity can be hard to distinguish. Especially in applications that have been developed over several years, not only the complexity of the code increases, but also the complexity of the business requirements. As long as the requirements are unnecessarily complex, it is difficult to translate them into good, maintainable code. The problem cannot be solved by refactoring the code alone. Instead, it is necessary to clarify together with product management exactly which of the requirements are still relevant and what can be simplified.
Personally, I find a balanced approach makes the most sense. You focus on the technical debt that currently hinders your daily work the most and leave the rest for now. This way you make sure that all changes have a direct positive impact on your work and your results.
“We absolutely have to replace some technology or framework, otherwise we have too much technical debt in 5 years.”
This is a really though situation. Replacing technologies or frameworks on which a system is built, in particular when the development has been going on for a long time (half a year is often enough), is really hard, costly and error-prone. This is especially true if the technology is tightly integrated with the code and many places have to be touched or rewritten.
One fact you should be aware of at this point: What is modern and state-of-the-art today will be outdated in 5 years as well.
So the question is: Is the trouble really worth it?
Certainly, new technologies and frameworks make many things better and easier.
But already Fred Brooks said: ‘There is no silver bullet’ - A new technology and a new framework may bring a few percent higher effectiveness, but they are NO game changer.
There will be no 10x acceleration in software development. Rather, there will be a long and tough period of transition until everything is running as before.
Is it really worth it? It depends on the specific situation. In my opinion, it is important to be aware of the actual benefits and costs in advance. In many cases, the benefits are significantly lower than expected and the costs, on the other hand, are significantly higher.
Tackling technical debt is a challenge for every team.
As a colleague so accurately put it: Today’s code is tomorrow’s technical debt.
All we can do is being aware of the technical debt, continuously work on the most important issues, and keep a good balance between tackling technical debt and developing new features.