Lately, I've come across a couple of blog posts like "Most Technical Debt Is Just Bullshit" and "Technical Debt Isn’t Real". They're discussing whether we twisted the initial definition of technical debt to mean anything and thus nothing. People have since then asked me about my opinion on the topic. So, here it is.
Before I start I'd like to state one thing I particularly don't like about any of those articles: Their catchy but aggressive titles. I've written about non-violent communication and I believe that if you want to have an earnest discussion you can't use such titles. This article contains my thoughts on the topic and I'm trying to keep emotion out of it.
I believe that when people argue about the definition of technical debt this is a symptom of a larger organizational problem. If engineering teams are not empowered to make decisions on their own this can lead to large-scale problems that no product manager will be able to solve. We need to acknowledge that it's impossible to avoid technical debt and we should, therefore, design our development process in a way to reduce it every day. One way of doing this is through continuous improvement which can come in all sorts and flavors. In the end, it doesn't matter so much what we improve but that we're improving the system because the alternative is doing nothing and this will always hurt us.
If you build a house today you'll have to renew the paint roughly ten years from now. This does neither mean that you were sloppy today nor that the paint you picked is bad. The paint wears off over time and at some point, you will need to redo it. Not the people or the tools are your enemies; time is.
Peter Hilton once told me "The moment you write a line of code you also put an expiry date on it". For me, this is what technical debt is all about. Making sure to refactor code before it reaches its expiry date. Because when this happens you end up in a situation where:
- developers aren't familiar with the used technology anymore,
- the system around the code has changed so drastically that it might be impossible to adjust, or
- it seems easier to rewrite the code instead of refactoring it (which means duplicate work).
In short, by not making sure that you update your code before it expires you create waste.
During my career, I got to see software development both from the perspective of an engineer and of a product manager. I've used a language that I would not use today and I've also heard other people make statements that sounded wrong in the past and ring all my alarms today. Let me give you an example.
As a product manager, you need to know when to take up technical debt
This single sentence might summarize everything that can be wrong in a company. I believe that as a product manager you should:
- make sure that the team(s) you're working with understand the problems they're trying to solve,
- that they have access to the customers who use their product, and
- that you are able to answer all the questions around problems and features they might have.
Should you be telling them how to solve these problems? Even more, that they should take on technical debt? I doubt it.
I now think that the real meaning of the statement above is
As a product manager, you need to make sure the team cuts corners to get those features delivered faster.
But this doesn't sound so good if you'd actually say it out loud. Even worse, this has nothing to do with technical debt. This is asking the team to ignore defects in the software to gain the illusion of speed. It's a bit like stating that breaks make a car heavier, and, therefore, slower so why not remove them?
Even if a product manager makes such statements this shouldn't affect the product. Why? Because it's still the engineers who build the product. They decide what to type into their editor. So, what might be the reason that teams still struggle with the topic?
Product management never prioritizes work to reduce technical debt.
And they don't have to. If you'd ask me I'd like the product manager to stay focussed on the customer. When an engineer says something like that I think in most scenarios it's because the team isn't empowered to make its own decisions. They might be used to a process where managers make decisions and the team then does the work. The company might even like this way of working. However, if you don't make sure that you listen to your engineers then it is only a matter of time until your software rushes past its expiry date.
The issue with refactoring is that the benefits are not as obvious as product managers would like them to be. You try to improve your code before it causes issues and this is hard to report on. Because you would need to measure the time not spent. That's an impossible task.
You will not be able to fix this with any spreadsheet. The only way out of this is trust.
- Trust your engineers that they want to do a great job,
- trust the teams that they prioritize the right work at the right time, and
- make sure the team has access to all information it needs to make these decisions.
I don't think there is a way to avoid technical debt. However, you can avoid bad code. Here's how I suggest doing that.
There will probably never be enough time to build all the features. So, when faced with a deadline I'd suggest to rather reduce the scope of the feature. Never "save" time by reducing quality. Because when you reduce the scope of the feature you still ship software that works. This means that when you continue with the next feature you don't have to spend a lot of time fixing what is already out there. In other words, you can continue to move at a steady pace.
When you reduce the quality of your software it means that you're most like busy fixing bugs you don't know about after you have shipped the initial version. This takes away time from any further feature development. If this means that the next deadline is also at risk you find yourself on a downward spiral where you spend most of your time fixing bugs and not building features.
One way of getting ahead of the management game can be a zero-bug policy. I would guess that it's pretty hard to argue against such a policy. It also gives the teams some leverage as long as they are the ones who decide what a bug is and what isn't. By immediately fixing bugs when you find them you make sure that you're always working on the best foundation possible at any given time. This usually leads to better software quality in general.
Also, this can lead to more time for feature development even though this might seem counter-intuitive at the beginning. Because when you make sure there are no unresolved known bugs then you also reduce the risk of "surprises". Any unresolved bug comes with a risk that something larger and unknown isn't working properly. However, if all bugs are resolved you reduce this risk as much as possible.
Everything I wrote above boils down to one basic rule. Never stop improving your software. Technical improvements are not projects or initiatives. They are something the team has to constantly do. Compare it to cleaning your bathroom. You wouldn't do that only once a quarter (at least I wouldn't).
A couple of techniques I've used in the past are:
I've constantly used this rule. Essentially it means that you should always leave a place a bit tidier than you found it. While this is also a good rule in the real-world it also helps to keep a software project up-to-date.
For instance, we have the rule to remove lodash methods for
reduce, etc, and replace them with their respective native counterparts. I did not want to turn this into a full-blown project because there is no big immediate benefit. In the long term, this means we're getting rid of a library that is no longer needed and can reduce our bundle size. Also, while
lodash might be known amongst developers right now this does not have to be true in the future so we're making sure that we're slowly but steadily getting rid of it.
On any given Friday the members of my team are free to work on any experiments they'd like to. This means they can test out a new library, spike on a refactoring, or try to build a feature they think is awesome. If they choose to not use the time that's also fine.
What I'm trying to do is give them a dedicated space to explore new ideas. Whether they're doing this is up to them. However, I'm also trying to lead by example and pitch ideas I have for possible new "Friday projects".
I've previously blogged about the difference between being busy and being productive. If the team is busy all the time then there is no time for reflection and improvement. That's why I believe you need to create an environment that prevents people from being busy all the time. Similar to "funny Fridays" this helps to create an environment where improvements can happen more naturally.
How is technical debt handled at your company? Do you have more rituals you'd like to see listed in this article? I'm interested in hearing about them!
You're a product manager and disagree with what I said? Also, please reach out and let's talk. I'm always interested in hearing other opinions.