Let’s start with creating context by defining what technical debt is, why it lowers the quality of our work as developers and why it is so bad that we can’t simply ignore it.
What is Technical Debt?
Technical debt (also known as tech debt or code debt) describes what results when development teams take actions to expedite the delivery of a piece of functionality or a project which later needs to be refactored. In other words, it’s the result of prioritizing speedy delivery over perfect code.
It is a concept in software development that reflects the implied cost of additional rework caused by choosing an easy (limited) solution now, instead of using a better approach that would take longer.
Why Should We Care About Tech Debt?
It is important not to let tech debt pile up, mainly for the long term success and sustainability of software products. Your system may have technical debt from past team members which would require the current engineering team members to figure out why someone did what they did and also how exactly they did it, so that they can backtrack and fix it. This is obviously a big vulnerability for the quality of the software and probably diminishes productivity because it would be very time consuming.
It also affects the motivation and mental health of the software team if your technical debt grows as your projects evolve. Instead of focusing on the good code you know you can write, you need to perform additional tasks to figure out how the current solution can be fixed or be fitted into the model at hand. As a consequence, there will be a continuous frustration within the team. Therefore, it’s good for us to take care of it asap.
One of the most prominent problems is the spread of technical debt across the code, as it not only affects the development team, but also any other department working with the product at hand. It may cause problems of delays when it comes to feature release, potentially affecting performance, scalability and maintainability. If you incur too much tech debt, it will go so far as to bring up bugs.
What Mistakes to Avoid When It Comes to Managing Your Tech Debt?
Here, there are a few things to watch out for and avoid.
The first one is the so called broken windows theory. Imagine there is a building and the building is well maintained, it has no broken windows etc. so you make sure it will stay as it is. However, the moment there is a broken window and nobody seems willing to fix it, the mindset of not caring can spread across the team or the scapegoating starts until the task is pinned on someone manually. Whereas, if you see that the building is regularly maintained and you break something, then you will fix it because you don’t want to be the first one to break it.
Moreover, if everything is broken, why should you personally need to be the one who actually fixes that? This line of thought brings about a snowball effect, which is related to the interest rate analogy above where the debt grows exponentially as you let it infect more parts of your system with the problems caused by non-optimized code.
You should not forget that even if you think you’re in control, the reality is that your tech debt is controlling you and dictating what you can and can’t do by limiting your options and capabilities when it comes to best practices. The restraint put on your system to find solutions that would support both the old code and new is not one to be overlooked.
Last but not least, saving time on the time to market by ignoring the tech debt can cause loss of business in the long run. In today’s market, where availability and performance are at high stakes, customers will end up leaving if the experience is not optimized. If they are faced with performance issues, bugs, scalability problems and the accumulated tech debt causes you to take two months to deliver a fix, your customers would have left for better solutions in the meantime.
What Are The Different Types of Tech Debt?
The quadrant above classifies tech debt.
You can have tech debt that you are acquiring deliberately for one reason or another, where you leave it for the future. It could be that you need to get to the market and you don’t have time now to do things perfectly, but you have a plan or you are conscious about the fact that you will need to pay it off at some point.
You may also be taking in tech debt accidentally. This may involve wrong planning in early stages or flat out not knowing what best practices to follow. The team would focus only on delivering what they are asked for, without following design patterns, SOLID principles and writing testable code etc. This is probably the worst path to follow where 100% failure is warranted.
Looking at the chart above, you could say that healthy technical debt is the right-hand column, and unhealthy ones on the left. In essence, there is a problem in the background, and on the right-hand side you’re aware of the problem, whereas on the left side, you’re unaware of those issues, and they will arise in the future to catch you unprepared.
What Are The Main Causes of Tech Debt?
What are the causes for code debt to come about, and what allows it to accumulate over time?
Weak leadership is one of the main causes in our opinion for allowing technical debt to increase and grow. At the end of the day, it may affect different departments but it is on the plate of the development teams. We can not just go and say to product teams, you deal with it, right? We need to train the team for having a technical vision spread across the company accompanied by a mindset for quality, performance, scalability, maintainability etc.
All of the requirements above are non-functional requirements that should automatically come along with the design of features, embedded into the software design process. It is about showing the team what to prioritize and that it is okay to take time to consider these things.
Unknown requirements can also be attributed to leadership in so far as how they decide to deal with those issues. The product team may ask for something without having an understanding of the tech requirements and that is normal. However, it may result in needing to change things later on because the customer wanted something else. That’s a healthy thing so long as the management can acknowledge; we had an understanding, but we need to refactor and then solve the problem in a different way. There needs to be a stage where the leadership realises ‘we need to clean up, we need to do a refactor, we need some time to figure out how to do it right this time’.
Additionally, requests for last minute changes need to be handled quite similarly. Leadership needs to be an umbrella for the team and that means not being a proxy of the pressures and creating the space for them to solve issues once and for all.
One of the other main causes for tech debt acquisition is – as we had mentioned above – not having the right mindset across the company or at least the development and product departments.
One apparent cultural issue is not having an environment where issues are handled collaboratively, within a tracking system that holds people accountable without putting them down.
The other one is having a culture of no testing, which causes a lot of fear of making big changes to the system. Let’s say, along the way someone made a mistake because there’s no testing and it broke other elements. This fear just spreads across the company and then no one wants to refactor things.
Then there is also lack of documentation and collaboration. You must have faced this or witnessed this at some point where someone asks for for help and nobody answers. Now, if you don’t know how to fix something, and if nobody wants to help or there’s no documentation around it, you would try to reverse engineer and figure something out, but it won’t be the best way to do it.
Last but certainly not least is time constraints,and these will make sense in some scenarios more so than others. For example, if you are working on an MVP, you want to get to market as quickly as possible to get a proof of concept and improve from there. We are not here to say this is not good, it is how most agile processes work but you need to spare resources down the line for what you neglect today.
The miscommunication or the lack of knowledge transfer between tech and business departments can also lead to incorrect timeline estimates. Our advice here would be to always assume estimates are incorrect and factor in some extra time as a buffer.
Managing client expectations plays into this as well. Business teams naturally will be eager to come to an agreement with the clients and buyers, which may not always involve a technical team member’s input in that moment. If your team has the mindset of checking in with engineers before closing down deals with clients, you can avoid unrealistic expectations and disappointing your clients by not honoring the original timeline.
How to Avoid the Vicious Cycle of Tech Debt?
Starting from the left, when you have high technical debt, your code quality is going to be poorer as a result of this debt. A case could be, you’re working on a rebuild and it doesn’t even have a unit test, or there is no demand for sufficient testing – you’re going to have low code quality, and that’s going have an impact on productivity. In the long term, the lower code quality is going to have more bugs and create more problems. This means you’re going to end up spending more time fixing things than you normally wouldn’t if you tackled problems in real time as they occurred. This puts a software team into a reactive mode, where you work on patching issues instead of working on designing long lasting, high quality systems.
Obviously, when the productivity goes down, then you’re going to get into trouble with the business side asking why are we not able to deploy new features now even though we were so quick on the first few deployments. Six months later down the line, we may be not producing anything, and doing crisis management even though we have more developers.
The tech debt that was incurred to increase productivity is now coming back with added pressure because we need to now increase productivity by eliminating the debt.
Moreover, every developer wants to work in a healthy environment, where you can do your best, improve on your skills in the job and work on innovative solutions. If you’re working in an environment with high technical debt, what happens is that you are just going to try to not break things, and may need to compromise on your code to sustain that.
This is where the vicious cycle doubles down on software teams because there is no motivation, no working environment, increased pressure and more complex issues than ever before to deal with in this mindset.
We have seen many times, and rightfully so, that software engineers jump ship because there are abundant opportunities in the market to work on much more innovative and modern solutions, instead of trying to fix legacy systems. If your developer retention rate goes down, and those developers go away with all the knowledge acquired, the new team members are going to find themselves in a turmoil where they start a project with lots of discovery on how to fix things. This is, if you can find the right people motivated enough to take on such a challenge.
It is crucial that the potential issues that may arise from acquired tech debt is communicated to the product and business and management teams. They need to know about these, and its possible implications on the product later on. This way, the trust in the team will not be broken by scapegoating people. Once the business teams acknowledges the issue, they will factor it in into their timelines and give dev teams the space to pay off the technical debt. In an ideal world, this needs to be part of a company’s strategy and goals to eliminate code debt.
How Can You Prevent Technical Debt from Accumulating?
1) Have A Vertical Vision
- The company aims to create a great product, not just features.
- All the related departments are involved, and aware of technical debt.
- Everyone should know that building great software takes time
2) Conscious Leadership
- Strong leaders to establish technical vision
- Take the pressure off developers coming from business/product teams
- Manage & control technical debt growth
3) Proper Process and Standards
- Design documents with approvals from stakeholders
- Documented & tracked technical debt
- Well-defined, and documented standards, best practices, design patterns and principles
- Code Reviews and regular testing in search for unacknowledged technical debt
- Sparing a fixed percentage of time for cleaning technical debt per sprint
- Allowance of time from feature to feature to do clean up:
- Focus on one feature at a time
- Clean technical debt and refactor
- Focus on the next feature
Final Thoughts on Tech Debt Inquisition
So, it is not the worst things in the world to have technical debt – when it is needed, it is needed just as you would take a credit when you are in need. It is simply a shifting of resources. What causes technical debt to have bad consequences is not managing it well. You need to be in control, and tackle it incrementally even if not all at once.
It goes without saying that quality plays a big role in the success of software businesses these days – if not for all businesses. With the increased competition and abundance of options in the market, releasing an inferior product to beat people to the market or to satisfy customers in the short run will interfere with the longevity of your product. Clients want stability and consistency as much as they want speed of delivery. They may be impatient at times, but if you answer their needs with a superior product that exceeds their expectations, then they will become loyal to your offering.