Do I have technical debt?
Things haven’t been going so well lately.
It’s been a couple of months since you and your team were able to complete a sprint successfully, without leaving any tickets behind. People are starting to mention technical debt but you don’t really know what it is. All that you are seeing is that simple functionalities or minor changes seem to be taking way longer to develop. The team’s velocity keeps going down even though everyone seems to be working extra time to meet the sprint goal. Besides that, bugs keep showing up out of nowhere. The more you fix, the more they pop up out of nowhere. Making any kind of schedule seems impossible and if it keeps going like this you can definitely say that you’re not going to hit your end-of-project deadline.
There might be a lot of reasons for projects not meeting their deadlines but if the situation sounds a little bit like the one above, then you should be looking more into what technical debt is and what you can do about it.
Why is technical debt so scary?
Well, it’s in the name. It’s debt and if it accumulates you might be spending all the resources that you have into paying that debt rather than generating business value.
I’ll spare you the technicalities. You can read here a short explanation of technical debt.
What’s important to know is that technical debt is normal on any project and it’s even useful. Whenever you need fast results and you “take a shortcut”, you create a little bit of debt. Sometimes, you will want to get fast results to meet a deadline, get a functionality out so it can be tested by users, or just show the stakeholders that you get things done and build some trust. That’s not a problem as long as you pay that debt (rewrite the code) sooner rather than later. Fast results now mean more work later. So, be mindful about when you choose to go fast and when you take time to fix things up.
But how do you know that you have a problem with technical debt and that you should start worrying about it?
- Functionalities or changes that seem easy on a first glance end up taking a lot more time than expected.
- Velocity is smaller than usual or is all over the place (in some sprints it’s low, in other sprints it’s back to normal).
- Releases are getting buggier. The more time you spend on bugs (anything over 20% should be a cause for concern) the more bugs seem to appear.
- Your tester seems to be overwhelmed at times. So, suddenly everyone starts doing testing to make sure all bugs are “caught” before the release.
- Sometimes, it seems that you are spending more time fixing stuff, rather than developing.
- Estimates (even simple ones) are hard to get right even when you add a buffer and take into consideration the worst-case scenario.
- Even though people seem to be working more than usual, deadlines either aren’t met or, when they are, it is because of some superhuman effort.
If most of these apply, then you probably have a problem that you need to fix. If only some of these apply or they apply to a lesser extent (for example not all releases are buggy but one in 2 or 3 are), then maybe you are somewhere on the edge and you need to make a decision. Pay now or pay more later.
So, you’re working with technical debt
It doesn’t even matter how you got to this point. It just happened and now, here you are. Your schedule is a mess. Releases become stressful and team morale is low.
What does this look like from your colleague’s perspective?
Technical debt makes coding a lot slower as there are areas that you need to handle carefully in order not to cause any more problems. Usually, it means that the code is written poorly and, if we’re talking about a big project, it might be the case that nobody in the team even knows what exactly that piece of code does. Changes in some areas need to be done in 10 different places and whenever a bug shows up, you’re not sure what caused it and need to spend a lot of time investigating.
Usually, developers know where these high technical debt areas are in the project and tend to avoid them. Working on a task that requires them to make changes to that code causes frustration (“Oh, it’s gonna take forever”) and anxiety (“I have to be extra careful who knows what I’m going to break”). It’s the equivalent of playing Jenga but if the tower falls then you not only have to clean everything up and put the pieces back together but you’re doing it while the pieces are on fire.
In order to make sure that the Jenga tower doesn’t fall, whenever a change is made extra testing is done by everyone in the team. Everyone, especially the tester on the team, is feeling the pressure of not letting any bugs go into production. This just makes tasks take even longer than normal and developers become “duck tape programmers” — trying to ship on time but desperately holding everything together behind the scenes.
How do I manage this?
First of all, I have to tell you that I lied. Remember a couple of paragraphs ago when I said that it doesn’t matter how you got here? Well, I lied, it does because how you got here tells you how you’ll get out.
High technical debt can have many causes:
- Sometimes it’s not your fault. This is an old project and you and your team “inherited” it this way or the stakeholders simply took the decision of going into debt knowing the risks because they needed fast results.
- Other times, the fault is somewhere in the middle — constantly changing specs and priorities meant that you had to be flexible and adapt. Still, you never tried to confront the stakeholders and explain that all these fast-paced changes will impact the quality of the project in the long run.
- And sometimes it’s completely your fault — you’ve underestimated the work that needed to be done, the team had a lot of junior programmers and, in trying to keep up with your initial estimations, you’ve opted a little bit too often for fast results rather than good quality. Or maybe you just didn’t put that much emphasis on good engineering methodologies like code reviews.
Let’s start off with the team.
I think the best way to manage this is to be honest. Just put it out there: “Guys, this is what we’re facing … I can see that you are frustrated, believe me so am I … Let’s see what we need to do in order to change the situation.”
- Have a meeting dedicated to technical debt with your team. Brainstorm ideas on how to fix the situation. Try to understand how you got there and identify things that can be changed. It is also very important not to blame anyone. Start the discussion with the mindset that everyone did the best they could given the knowledge and information that they had at that specific moment.
- Adopt good work methodologies and stick to them (unit testing, code reviews even peer programming can work). Remember what John Wooden said: “If you don’t have time to do it right, when will you have time to do it again?”. So start working on doing things right from the start (or at least from now on).
- Make a wall of “Technical Debt” . Put post-it notes on it with areas or functionalities that you know need refactoring. Start including these in your sprints one by one while still delivering business value to your stakeholders. This will also add a new sense of ownership as everyone will want to get rid of the post-it notes on that wall.
How do I manage technical debt with the stakeholders?
You need to talk to them in order to fix the problem, just like with any other. Be honest about the state of the project and explain to them the concept of technical debt. If stakeholders aren’t aware of the concept of technical debt, they will award fast shipping rather than quality. Once they become aware that fast comes with a cost, they might start thinking differently.
Nr.1>
The ones that knowingly took decisions that increased technical debt (“We need this big functionality by next month”). You will have to prove to them that although they seem to be getting results fast, this will hit them hard in the long run. Also, changing specs in the middle of the sprint isn’t useful either. Practically, you have to convince them that you need to go slower or everything will fall apart. You might find that they don’t trust you (“It worked fine until now. It’s not going to crash if we do this little thing also. Don’t worry and just focus on delivering.”) so you will need data to prove your point.
- Burndown and velocity charts showing the amount of work being done with the current state of the project. This will help you keep track of how much time you are “winning” once you start fixing technical debt issues.
- A ratio of time spent developing to time spent fixing bugs will be useful. Developing brings value, bug fixing doesn’t. If your team is wasting 30% of its time looking for and fixing bugs then you aren’t delivering value 30% of the time (translate this into money for a bigger impact).
- Examples of bugs that almost made it live and could have had a big impact on the business. Give a real example (“Last month we had a bug that made you unable to introduce your credit card details if you had a discount on your items”). It will make them pay more attention.
- A short description of the state of the team. The goal here is to make them understand that if the team is frustrated or in burnout, then you won’t be able to deliver either quality or quantity
Nr. 2>
The ones that weren’t aware of the risks or didn’t know you were taking shortcuts. This happens especially when, trying to meet deadlines, you prioritize speed without addressing potential downfalls. Maybe if you communicated more clearly and made sure they understood the risk of a tight deadline, they would have changed the schedule and things would have been different. Or you should have put more focus on good engineering methodologies and made sure functionalities were developed with code quality in mind.. Anyway, what is done is done. Just know that, depending on how bad the situation is, you might be facing a lack of trust (“Your team wasn’t able to deliver quality!.”) or you might gain some trust (“Thanks for making us aware of this. It’s true the last couple of deadlines were hard to meet. What do you suggest we do?”). Here are a couple of ideas:
- First of all, a clear discussion regarding what is happening, how you got there, what technical debt is, and the downsides that you are facing. Bring a list of areas that need refactoring and potential risks to the business if it doesn’t happen.
- An updated schedule showing how milestones need to change in order to develop new features and work on the technical debt at the same time.
- Details on other solutions found inside the team and how this will help reduce bugs and increase quality.
- A list of what you need from them. It might be anything from putting a stop to new functionalities until you pay some of the debt, to moving some of the deadlines a little bit further away or adding another developer to the team. Make sure you discover a solution that satisfies both your requirements and theirs while keeping both in mind.
What do I do now?
First of all, start by asking yourself: do you have a problem and need to deal with it right now? Or is this just something you should be thinking about, making sure it doesn’t happen in the future? If the problem already exists, make sure you have a clear understanding of the impact and communicate it to everyone involved. If it’s not a big problem yet, take some preventive actions like implementing good coding practices and making sure you are always communicating possible downsides to the stakeholders whenever you feel that one of their decisions is putting you into debt.
Before leaving I’m going to remind you just one thing: technical debt isn’t always bad. You just have to keep it under control.
Oh, and here is a quote I think sums up this idea pretty well:
“Shipping first time code is like going into debt. A little debt speeds development so long as it is paid back promptly with a rewrite… The danger occurs when the debt is not repaid. Every minute spent on not-quite-right code counts as interest on that debt. Entire engineering organizations can be brought to a stand-still under the debt load of an unconsolidated implementation.” — Ward Cunningham