Tech debt represents an accumulation of conscious or subconscious decisions which can now be identified as bad decisions. Basically, a shoddy job that makes taking the next steps harder. The more tech debt you have, the harder you have to work to make new changes.
My approach to system architecture and evolution is via continuous learning and improvement. I believe that all things change all the time. So all parts of a system will carry tech debt some time or the other. The developer team’s job is to continuously identify these parts, prioritize the critical deficiencies which are blocking the way forward, and consciously deepen their understanding of the system by taking on controlled tech debt if required.
This article is just a few observations about this phenomenon, mostly focussed on change and uncertainty.
Every decision is tech debt in the making
- The reason we see so much tech debt, even in good teams and organizations, is usually not because of bad decisions. Decisions were probably good when they were made, but the world keeps changing. Parts of even good decisions will end up being tech debt at some point in the future.
- No one designs bad systems deliberately. If a decision looks bad today, it does not matter why it was taken. Maybe the team didn’t know any better, or the world changed on them. The outcome is the same either way – we need to do something about the situation.
- The ideal architecture is only ideal at a point in time. Perhaps not even then because there are almost always things we do not know that might lead us to design our systems differently (Conway’s Law).
Tech debt is great when taken deliberately
- A lot of discussion around technical debt is only about technology quality. It does not talk about learning.
- Deliberately taking on tech debt allows us to learn faster by shipping faster.
- The problem is that we forget that we made the feature as a learning step. The context of that deliberate decision is lost. So when the next iteration comes around, the decision looks like a bad decision rather than a feature in process of growing. Too often, engineers think on the lines of “we built it badly and need to fix it” and not like “which part of this system should be evolved next”.
- The more we remember as a team, the more we can think of tech debt in terms of WIP features rather than an already finished piece that was designed badly.
The location of tech debt matters
- The place where technical debt is seen in the overall system matters.
- At the edges of the system, where the most amount of learning is happening (like customer-facing product teams), tech debt is tolerable, even somewhat desirable (as mentioned above in the context of learning). It is less tolerable in the deeper layers of the system because the deeper in the tech stack a system is, the more dependencies it has, and therefore the more damage a bad decision can do. The more stable the core systems are, the more fearlessly we can mess about in the other places.
- Platforms architecture actually encourages this type of dual-thinking. It establishes standards for the platform components and allows product components to do whatever they want, however they want it.
- This is a point in time argument – there is no “core” as such. Since all systems are always evolving, even core components will change. When that happens, we should apply this argument to them too.
Tech debt is a balance
- The trade-off isn’t between speed and quality. The tradeoff is learning and executing on that learning in the long run.
- I wrote earlier about ditching the urgency to execute in the learning phase. This is where it is okay to take on tech debt. Build something small and fast to see what the users do with it.
- Now while the user feedback is coming in and we are trying to understand it, clean up the most undesirable of the bad decisions you have in the system.
- BOTH THE ABOVE STEPS ARE CRITICAL. It is inevitable that we will go back and forth to some extent.
The origins of tech debt are important
- I mentioned earlier in this article that why we have a bad decision right now doesn’t matter. What matters is to fix it. This is true from an operational perspective but not from a growth perspective.
- For the engineering team, identifying the origin of the tech debt is a critical part of the learning process.
- Looking back on their decisions, can they identify the bad decisions that they then thought were good? What led to those decisions? This will typically reveal some sort of information gap – not having enough technical skill, not having enough knowledge about the product or the customer, not understanding the direction of the organization etc.
- These gaps can then be filled actively.
- This is hard because teams are biased against their former selves due to the new knowledge they have gained since a decision was made.
If you liked this, subscribe to my weekly newsletter It Depends to read about software engineering and technical leadership