You keep using that word. I do not think it means what you think it means.
- Inigo Montoya
Tech debt is a term that’s tossed around a lot in software. I haven’t worked at a company that didn’t talk about tech debt. I haven’t been on a development team where its product owners weren’t in some kind of tug-of-war with the devs over mounting tech debt. It’s a permanent fixture in the software industry. A fixture I don’t think is well understood by either side.
To that end, I want to accomplish a few things in this article. I want to provide a frame shift on tech debt. I use frame shift as a way to say stop using the term Tech Debt! I also want to break down some meaningful, practical, day-to-day ways to discuss and practice software maintenance.
tl;dr
Stop paying down tech debt and start actual software maintenance. That’s the real term we should all be talking about.
The frame shift
debt: a state of being under obligation to pay or repay someone or something in return for something received : a state of owing
The term debt is an abstract concept for a lot of folks. It’s hard to reason about. You spend money that you don’t currently have, but then you need to pay it back, often according to complex terms, at a later date. To me, that doesn’t relate to writing code. Code written is not something to be paid back.
That gets us to the core of the issue I have with the term Tech Debt. I’ve been searching a long time for a definition that my peers and I can use to gain a shared understanding of what we’re talking about when we trade tech debt around.
Those who write software have a list of things that need to be fixed, moved, rewritten, etc. Product owners/managers often look at it as something dragging the team away from shipping features. Oftentimes it’s shaky foundations that were rushed into place to hit hard and fast deadlines. Sloppily written, insecure, unmaintainable code. We’ve all written it.
There’s loads of reasons why unmaintainable code ends up running in the systems our products are built on, but none of these fit the definition of debt.
Instead, I propose we drop the term Tech Debt and start talking about maintenance tasks. Maintenance is what we’re really talking about. When parts on our car or bicycle suffers wear from driving them around, we don’t talk to our mechanic about “mechanical debt”. (Go back and re-read that sentence, but replace things with “software” and “programmers”). We talk about maintenance.
We weigh and consider the maintenance that needs to be done to ensure that our machine (software) will continue to work the way we want it to. When something breaks or we can start to see wear, we start to consider when we should replace it. How important is it? How long will this part last until we absolutely need to relpace it? We want reliability, but we also want (and sometimes need) to weigh the costs of reliability.
maintenance: the act of keeping property or equipment in good condition by making repairs, correcting problems, etc
Maintenance is how we achieve reliability in many parts of our lives. Cars, bicycles, houses, mental health, relationships. This is the frame shift I’d like our industry to adopt. Maintenance is an easy term for nearly anyone to reason about. All of us have maintained something in our life. Yell it out! Maintenance is the new Tech Debt.
Changing discussions about maintenance
Now that we have a new frame of reference, think back to discussions you’ve had with your teams about maintenance. Would you word things differently? Would product owners hear things differently? To set the stage, I want to introduce a good metaphor to use in these discussions.
[Note: I want to acknowledging that not everyone understands the mechanical workings of an engine. If that’s the case for you or your team, try to use a similar metaphor from other relatable examples like bicycles, houses or apartments, mental health, or relationships.]
Fresh oil keeps an engine running smooth. Over time exhaust and debris are picked up by that oil. It becomes thicker and more viscous, and the engine struggles to run smoothly. Eventually, if the oil is not changed, the engine will start to overheat, slow down, and there’s a risk the engine explodes or seizes. Sound familiar? Software projects need the “oil changed” regularly to maintain velocity. Unmaintainable code or parts that were never meant to last to the current scale will pile up.
This is the wear and tear of the software. Preventing friction within a system is what we’re trying to achieve. Without doing maintenance, things can reach a point where making changes and adding features causes code maintainers to slow down, burn out (overheat), and sometimes, leave an organization altogether (exploding/seizing).
An important thing to raise is that discussions on maintenance need to be a two-way street.
- The folks building the software (writing the code) will raise the alarms and claim the need to stop and do some maintenance, otherwise things will start to break down.
- Product owners will claim that paying client features are more important than the maintenance. Round and round it usually goes.
These discussions need to be approached with a healthy perspective from both sides. When engaging as a software engineer, remember to ask and be curious about the pressures and considerations the product folks are under. Hopefully they’re not just knee-jerk saying no out of habit.
As software engineers, we need to take a professional approach. There’s external factors we may not be considering that need to be weighed when faced with the decision to stop producing features or do some maintenance.
From the product owner point of view, there needs to be trust that the software engineers building the product know what they’re talking about. Trust that things will slow down and possibly crash without maintenance.
Methods of maintenance
Now that we know how to talk about maintenance, let’s implement it and celebrate it out the other end. Be proud of it. Talk to your customers about it. Talk to your stakeholders about it. Brag to your significant others that you not only build great software, but that you also maintain it.
There’s a few methods I’ve seen work to tackle maintenance.
Planning
A key step to ensuring maintenance is done properly is planning it. No different than a sprint planning session, have a maintenance planning session. Have the team come together with the warts, the things they hate, the stuff that slows them down, causes them stress, and contributes to their burn out. Be frank about what’s going on, then work together to make a plan on how to make it better. Keep track of the plans and assign work.
Executing
Every time you touch some code, clean something up. One of the simplest and easiest ways is to start right now by adopting the value of leaving the world a better place than you found it on your team. Make and enforce rules around it. Put it in your PR checklist. An example rule: once a feature is done and merged, the owner is free to take an hour(s) to clean up something. These little things can be so rewarding over time. Now, this type of maintenance is good, but not without downsides. Some pieces of maintenance are too large for a one-hour or drive-by cleanup. For those tasks you can use the next bit.
Build it into each sprint
Take a chunk of every sprint and agree with your team that 10% of the total sprint time is maintenance work. Figure out if 10% is enough or potentially too much. Back of the napkin math: 5 team members working 40 hours per week is 200 hours. 10% of 200 is 20 hours. Is 20 hours enough for one person to do maintenance properly? Maybe you have two week sprints and can spare a whole person for a week to do maintenance? Your team, your rules, but it’s a good way to build it in. One piece of advice I would offer is that as few people as possible should be working on the maintenance. Splitting that 20 hours 5 ways and expecting good focus across all team members is not optimal. Get the team together, plan out maintenance tasks, ensure they’re clear, then let someone or a few someones focus on that. It allows your team to continually ship new features while also crushing the maintenance tasks. If you have even larger tasks to tackle, the next bit will cover that.
Take an entire sprint off every now and then for maintenance
Schedule it in advance. Make everyone aware. Stakeholders, clients, etc. It’s something that I rarely ever see done, but has so much impact. For some reason, product owners seem scared to declare that products need maintenance. If I were a paying client and someone told me that they had a planned maintenance sprint, I’d take that as a good indicator that they’re paying attention to getting ahead of problems instead of waiting for an unplanned outage to happen. Book a maintenance sprint a month out, let people know your motivations, do some maintenance, and get back to regularly scheduled shipping. Ensure the team can plan ahead for a maintenance sprint and get their ducks in a row, then get to executing on the sprint! I can guarantee you’ll have nearly 100% engagement, and an air of excitement from a team that’s given the proper freedom to do the maintenance needed to make the product they work on great in their eyes.
tldr
Quickly, here’s a list of things that can help you and your team stop talking in circles around tech debt and get down to the real business of doing maintenance.
- Change the terminology: stop using tech debt, start using maintenance.
- Find a metaphor that works for your team to understand the what and why of maintenance.
- Start planning out maintenance tasks. Make it as habitual as retrospectives and sprint planning.
- Form some rules around how maintenance gets done, make it rewarding. Leave the world a better place.
- Book the time to do maintenance. Elect folks from the team to own the tasks, make it a meaningful part of work.
- Take an entire sprint off to organize the team and the maintenance tasks. Set yourselves on level ground and run from there.