Technical debt isn’t what you think it is.
Kellan Elliott-McCrea wrote up an excellent commentary on tech debt back in January ’16. He makes some fantastic points that help clarify what tech debt is and isn’t, but I’ve still been feeling like something is missing in his definition. I think I’m starting to get a handle on it.
What Is Technical Debt?
Kellan tells us that technical debt as “… the choices we made in our code, intentionally, to speed up development today, knowing we’d have to change them later” is rare. I definitely agree with his sentiment. He goes on to identify five types of things that we usually mean when we talk about technical debt:
- Maintenance work
- Features of the codebase that resist change
- Operability choices that resist change
- Code choices that suck the will to live
- Dependencies that resist upgrading
This is a great classification, but I think fundamentally, he’s talking about outputs, not inputs. I’d like to get one level closer to a root cause. Based on his taxonomy, I’d say that technical debt is “the accumulated inertia from conscious trade-offs.”
Technical Debt Is Not an Accident
I use the term “trade-off” very intentionally here: I am purposely not saying “shortcut.” In my experience, I agree with Kellan–tech debt as “shortcuts that are going to bite us later” are quite rare. However, trade-offs that make thing A simple and thing B more difficult are quite common and not always avoidable.
For example, when you add an index to a database column, you’re making a trade-off. You’re saying read performance is more important than write performance or space efficiency. Most development includes trade-offs like this, because we value one or two of these things:
- Performance – faster for the user
- Comprehensibility – easier for a developer to understand
- Development time or cost – easier to write
- Ease of deployment
- Testability – easier to test
- “Hipness” – (also known as “that’s just not how things are done anymore”)–the one point on this list that most often ends up being the wrong thing to value
The items we don’t focus on are then necessarily deprioritized.
Technical Debt Is Not a Mistake
The developer who came before us isn’t a bad person for leaving some tech debt behind. He or she didn’t make a mistake. It was almost certainly a calculated, careful decision made with incomplete information (and the information is always incomplete.) In all likelihood, the original author carefully considered the trade-offs and decided to emphasize one of the items from the list above over the others. And today, the factors that he or she considered have changed.
We should not let our stakeholders see tech debt as a mess we’ve left behind because we’re moving too fast to clean up. We aren’t bad people for having left some debt behind, and it’s not a screw-up. Rather, it is almost always that we made a good decision earlier, at the point of maximum ignorance, and we know better now.
Moving Past Technical Debt
We need to stop beating ourselves up over knowing better today than we did yesterday. Stop taking a sprint to “deal with tech debt,” and start taking time to “implement the lessons we’ve learned over the past X sprints.” When technical debt is just “work” and we can discuss it on its merits and without emotion, we’ll be able to prioritize the things that matter, keep velocity up, and improve quality. But you can’t do that if you’re throwing blame around, hiding embarrassed, or glossing over a “mistake.”
There’s no such thing as technical debt—just technical work.
As developer I am totally agreed, sometimes it’s so import hug the risk to obtain the goals fast, this trade off for me is absoluty normal in nowdays. The problem for me is forget all the Technical Debts forever, this is the mistake and the point, so keep in top of minds of the team to use each litle opportunity to improvement the codebase and remove the Technical Debt, just do it! Nice post!
I’ve come to see having Technical Debt (TD) as a sign the development process is doing things properly and it was a John Carmack tweet that put me on to this idea ( https://twitter.com/ID_AA_Carmack/status/515873591515049984 ):
We’ve all come to see premature optimizations as a bad thing. It’s easy to recognize and to call it out. But Carmack tells us that premature [insert any developer activity] is equally bad. In the case of TD the fact that you’ve acquired some sub-optimal code is a sign that you’ve properly avoided premature design. Cleaning up TD is just another kind of optimization activity. Instead of optimizing for code speed, cleaning up TD can be optimizing for readability, flexibility, reusability, etc.
So if you are having difficulty selling this activity in a sprint, don’t call it TD, instead use the Premature Optimization banner to describe this phase as optimizing activity. If you need a metric to measure success, you might try counting the lines of code removed.
Thanks for sharing that, Mike. I hadn’t seen that tweet from Carmack before but I think it’s on point. It’s a great short way to summarize some of these ideas.
Unrelated (and late to the party) it feels like the end of an era to see John Carmack on twitter, after having followed his .plan file from id Software way back in the 90s.
Comments are closed.