For a brief, but an enlightening article on Technical Debt (TD), do read this post from Martin Fowler Technical Debt. My focus here is not about what TD is, but rather some thoughts on WHEN in time do you incur it. Knowing that can help you go in with eyes wide open and maybe reduce the debt burden a bit. To assume you will not gain TD means you are either just out of school with no real-world experience or plain naive (no offense to anyone).
First things first. When you look at the grand scheme of things, taking on TD at times is actually not a bad thing. Ok, slow down before you throw those rocks at me! For example, if you are a startup that is trying to create a go-to-market MVP in a competitive market, you will not have time to build the perfect team, the perfect design, or the perfect solution. There are limits to each, so quick decisions have to be made. Those decisions will incur TD, and I say that is OK. No point in having low TD, but being late to the market. The same reasoning holds true for larger enterprises working in competitive markets.
The cardinal sin with Technical Debt is when you do not recognize the act of taking on Debt or look the other way, with absolutely no plans or interest to resolve it in the future.
There are many ways to shape the software you are building. Ten engineers will have 10 different ideas on what is the best way. Each will have its pros and cons. Each might work just fine for the immediate near term, but the best solutions prove their worth over an extended span of time by
- Making software easier to understand (it is clear what the code does and often a reflection of good or bad design)
- Making software easier to enhance (in terms of figuring out where to make the change, the time to do it, and how contained a change can be without disrupting the codebase, therefore, reflecting poor design)
- Making software easier to test (good designs & abstractions make for better testable code)
Now going back to WHEN we incur debt. Of course, it is easier for us to see the TD being incurred while the code is being developed. But pause a bit and you will see that we actually might have started incurring the debt much earlier, even before a developer started writing the first line of code. The following factors play into that
- Limited Time (market or competitive factors drive business to aim for aggressive deadlines)
- Talent Availability (and when you can bring them aboard)
- Scope Confusion (yes Agile is built to handle this, but when you face chaos with scope combined with the previous two factors then tough times are ahead)
So to our business partners and all other non-developer stakeholders, your actions will have caused TD to be incurred before the development even started. Being aware of that is a strength and that knowledge can arm you with the tools to try and reduce that burden for the product.
Finally, here is one more point in time(s) where you will earn Technical Debt. Even well-written software (with low debt) running in production will incur new Debt over time, even if you do not make any new code changes. Now how can that be the case, you say? One simple example, software libraries/frameworks that you use (like open-source ones) have new versions created over time. New versions fix bugs, including security issues. This is the debt you earn. It’s like a house that grows old and things start to break down over time, even though you are not making structural changes. Other changes could be in infrastructure (OS, VM, Containers that you need to upgrade to). So just the way you earn debt before any code is written, you will earn debt when software just sits in production without any changes over time. Watch out for this too and get ahead of it.
Note: In no way is this article trying to justify engineering teams making poor design decisions. They squarely own that and will need to fix it over time.