How to manage Technical Debt

Technical debt is inevitable but manageable. Dino maps out its causes, impacts, and strategies for balancing speed and code quality. Learn how to repay debt incrementally, make better design decisions, and turn technical debt into a strategic advantage.

How to manage Technical Debt

If you are a software developer, there is no doubt that at one point or another, you experienced something called technical debt. As a matter of fact, you have most likely experienced it many times throughout your career, and chances are you are experiencing it right now. Whether you heard about this specific term or not, technical debt is something that is present in every developer’s life, and it has been the subject of many discussions.

So, what is technical debt? The Software Engineering Institute at Carnegie Mellon University provides the following definition:

Technical debt conceptualizes the trade-off between the short-term benefit of rapid delivery and long-term value.

That definition is short and precise, but for the sake of clarity let’s also include this one:

Technical debt is a concept in programming that reflects the extra development work that arises when code that is easy to implement in the short run is used instead of applying the best overall solution.

We’ve all been there. Whether the reason is unclear design, tight deadline, customer pressure, lack of documentation, no tests coverage or simply sloppy coding by an inexperienced developer, if technical debt is not repaid, interest slowly accumulates over time, making it harder and harder to repay. This makes technical debt similar to monetary debt.

Technical debt can turn a task which at first glance seemed trivial into something much more complex and time consuming than initially expected.

For example, a developer can give a small estimation for a small task because he knows it won’t require much work. However, after inspecting the code more closely, he realises that the project has many flaws, so a simple change in one functionality could break several other functionalities, leaving the entire project in a worse state than it was before, as proper design patterns were not followed. It goes without saying that this can lead to breaking deadlines, leaving the client unsatisfied and distrustful towards the developer.

Also, too much technical debt on a project is one of the biggest causes of low morale and developer dissatisfaction, so learning to handle it should make your life more pleasant.

Is it evil?

Does this mean that technical debt is evil? After all, we’ve been taught to write good code and avoid taking shortcuts (also known as “ugly hacks” in the community). Every minute spent on badly written code counts as interest, so all technical debt must be bad, right?

Well, no.

Although technical debt can easily lead a product into a disaster, it can be a very useful tool for a startup. First of all, let’s face it — customers don’t really care about our code. They only care about the product. For a startup this means that doing the required work in a timely manner can be a matter of life and death.

In startups you often must take shortcuts. You don’t know how your final product will look. You don’t even know if anyone will use it. You might need to pivot, and even trash half of your code. It might be logical to “do it well from the beginning” but one of the main characteristics of startups is speed, and getting the product on the market.

Sometimes you just don’t know if the startup idea will work at all. So instead of spending several months developing a code-perfect app only to find out nobody actually wants it, you might as well just release features as quickly as you can, and watch the key business metrics. After you find out what it is that customers want, you can throw away code for features that didn’t take off, and properly rewrite those which got positive feedback.

Maybe you’ll need to rewrite the entire project, but at least you know the idea works! If not — it’s not too bad because it didn’t cost too much anyway. Software purists might consider this heresy, but in startup world it is a very plausible scenario.

So, technical debt is not evil — it is merely a tool. And keep in mind, almost all startups do it. It is not an outlier, it is mainstream! But you can’t stay in debt indefinitely. Sooner or later, it will start slowing you downFinding that fine line between development speed and code quality is the key to success, and developers struggle with this on a daily basis.

Forms of Technical Debt

Technical debt can occur in many forms in a software project. Some are more dangerous than others, so let’s split them into two categories: Type 1 being debt that can hurt your project and Type 2 being debt that can kill your project.

Type 1 (will hurt your project):

  • Badly designed code
  • Ad-hoc architecture
  • Lack of test coverage
  • No code review process
  • Missing documentation
  • Lack of Continuous Integration and Continuous Delivery

Type 2 (can kill your project):

  • Using unstable technology
  • Relying on unmaintained open source
  • Improper algorithms and data structures
  • Wrong choice of programming language
  • Skipping design phase of project altogether
  • Wrong choice of communication protocols

Keep in mind, just because debts that fall into Type 1 may pose a smaller threat than the ones in Type 2, that doesn’t mean they should be disregarded. Writing fragile spaghetti code will slow your project significantly, just as the lack of CI/CD processes would. But if you wrote the entire project in a framework that has stopped being maintained or lacks features crucial to your project, there might not be a chance for a redemption without a full rewrite.

Good Technical Debt vs. Bad Technical Debt

Just like a house loan or a car loan are generally considered acceptable types of financial debt, we can describe different circumstances under which we take on technical debt by using the technical debt quadrant:

The Bad:

  • In the Inadvertent and Reckless quadrant are the developers who just don’t know any better. They aren’t aware that their actions are piling up debt. You should never take this kind of debt.
  • In contrast, developers from Reckless and Deliberate quadrant know that they are accumulating debt but they are covering it with excuses such as “There is not enough time”, or “We already took a shortcut on the other part of the project”.

The Good:

  • People from Prudent and Deliberate quadrant make a conscious decision to take a debt for a specific business purpose with a plan to pay it back later. This is where you want to be!
  • Finally, the Prudent and Inadvertent quadrant is when you just couldn’t avoid a debt, even with your best intentions. This quadrant is not worth thinking over, because it is not something you can influence. You can only hope it won’t happen the next time.

The design payoff line

The design payoff line shows the amount of functionality which allows to trade off design quality for time to market.

As you can see from the pseudo-graph, as long you are under the design payoff line, it may be worth implementing new functionalities without paying much attention to design.

Of course, the biggest challenge is finding where exactly that line is. This question is extremely hard to answer, as there is no simple way to measure design quality or measure productivity. It varies from project to project, and it can only be guessed.

In Lean Startup philosophy, this line can sometimes be placed on the point of the MVP (Minimum Viable Product) release. In other words, when you release a product with just enough features to satisfy early customers who can provide feedback for future product development, you need to start thinking about scaling up and repaying technical debt. Failing to do so will drain the productivity of the entire team, leading to slower and slower output.

How to repay technical debt?

Making time to repay technical debt is one of the most important, if not the most important step in the entire process. It’s highly unlikely that you’ll be able to convince management to let you stop working on new features and bug fixes in order to repay technical debt.

So, taking several weeks in order to refactor the entire project is not an option. What can you do? Boy Scouts have a rule regarding camping, that they should leave the campground cleaner than they found it.

How does this translate to software development? Each time you find a small instance of bad code which won’t take long to fix, do it right away and don’t introduce new bad code. Just like boy scouts don’t need to ensure the entire campground is cleaned up but just cleaner than they found it, you don’t need to fix everything at once but only ensure that with each commit you leave the code slightly better than you found it.

This principle can help you increase the quality of your code over time while continuing to deliver value to your customers. Keep in mind that developers who learn how to pay technical debt and clean up messes without extra resources are very valuable, so the benefits of going the extra mile are well worth the effort.

Having well-tested, modular components will significantly reduce your development time in the long run, when you start reusing them in different parts of your project. If your code is modular, it is easier to fix independent modules because the changes won’t affect the rest of the project — it’s just like walking in a hazardous environment in a protective suit.

Another good practice is repaying a small amount of technical debt every time you finish a task quicker than you planned. You, the entire development team and everyone who comes to the project in the future will be very grateful for it. Constantly talking with colleagues about repaying technical debt is also important, because having a shared sense of responsibility makes the entire team more efficient.

If possible, technical debt should be repaid regularly, using the boy scout rule. High interest debt should have priority over low interest debt, which doesn’t mean you should quickly jump to the most complex cases. Keeping debt-ridden parts isolated is a good practice in order to avoid introducing new debt where old debt has just been paid.

Code reviews, tests and code automation should be a no-brainer, but it’s surprising how many developers don’t take this seriously. Discovering and fixing a mistake before it’s actually integrated into the system is extremely valuable, as it doesn’t introduce any new technical debt to the project. Also, you should try to avoid taking bad (reckless) debt and have a repay plan ready in advance.

It’s always a good idea to communicate your progress to the management. Having people excited about what you’re doing is an important step in getting the project cleaned up. Even if the stakeholders don’t care about how you just removed dozens of lines of duplicate code, they will be more than happy to hear that your refactoring helped fix that bug that has been present for months but nobody wanted to tackle it, or that you will now be able to modify large features more easily because your codebase has just become more flexible.

The Vicious Cycle

The Vicious Cycle of technical debt is unfortunately something that happens to a large number of startups, and is the worst possible scenario.

Whatever you do, you do not want this to happen to you.

This happens every time when the accumulated technical debt is neither properly managed nor systematically repaid. You enter a never-ending cycle where more and more interest is generated, slowing down the entire project. This leads to more pressure from the customer which accumulates even more debt, restarting the cycle over and over again, slowly leading the project to its failure.

Conclusion

Technical debt is a part of every developer’s life and it is not something you should try to avoid. It should be used as a tool in order to achieve a specific business purpose. However, failing to repay accumulated debt can slow your project significantly, which can ultimately lead to the vicious cycle that spells doom for your startup.

That’s why being aware of technical debt and regularly making time to repay it is of vital importance to every software project. Repaying debt in small chunks regularly is the key for improving the overall state of the project. With just a little extra effort, it is possible to keep adding new value to the project while keeping it clean, or at least cleaner than it was before. It’s all about the discipline.

So remember to manage your debt responsibly!☺️