Building technology product is a complex process. Building products for a particular use case while working in a fast-growing startup is even more challenging. In most cases, you have either ship product quickly or risk failure in that market. Over the last few years, I had numerous conversations with developers, engineering, and product leads in such organizations. One of the most burning issues I found was technical debt. Atlassian defines technical debt as the "difference between what was promised and what was delivered."
Most agreed-upon reasons for the definition of technical debt usually linger around the following phrases -
- It results from engineering (or development teams) taking shortcuts while shipping a product.
- It results from prioritizing speed over-optimization while writing code and shipping the product.
- Poorly designed or thought-through architecture constitutes a technical debt.
Technical debt not only creates problems in the long term but, in the short term, results in critical bugs that can ruin the end-user experience and taint your business image. Various teams worldwide have created their methodologies for defining (remember, defining the problem well is essential before we start solving it) and resolving technical debt. But the question remains - Is there a way to reduce the technical debt without compromising delivery speed?
Plan better - But how?
While trying to answer the question discussed earlier, the most agreed-upon answer is - software teams have to plan better. Many companies have started building architecture teams to address the issues resulting from poorly designed architecture. Similarly, there are automated tools in place to check the code quality and do testing. Excellent observability tools give you a 360-degree view of all that's good and bad with your system. Modern CI/CD tools allow you to ship reliable software rapidly. And yet, tech debt continues to be a big problem. So, simply saying that we need to plan better is a wild understatement.
Hi there. Before presenting the solution, I decided to do a shameless plug. If you want to learn how to create kick-ass technology products, I have created a dedicated learning community called cloudeasy.club just for you. By joining this club, you can learn about system design, software architecture, and distributed systems. You will also learn about Org. design for engineering teams and how to solve real-world problems while shipping technology products. You can find us on Discord or Whatsapp group. Also, feel free to ping me on LinkedIn or Twitter if you have any questions.
The usual suspects
During my conversations, I compiled the following list of the most frequent reasons that are considered as "failure in planning" and lead to technical debt.
- Incomplete product requirements documentation - Ask a Product manager if the PRD is complete, and in most cases, the answer will be both yes and no. Even though product management is a relatively new field, there are hundreds of templates and books on writing good product requirement documents or defining the product problem statement well. But even with all this content available, prioritizing speed over-optimization often results in incomplete or poorly defined product requirements, inadvertently resulting in technical debt.
- Ambiguity resulting from the edge and corner cases - Most bugs result from the unthought edge and corner cases. You're mistaken if you think edge and corner cases are only relevant to writing code. Product features, architecture, communication within (and outside) your system etc., all can have ambiguity resulting from edge cases, corner cases, boundary cases etc.
- Non-functional requirements need to be adequately explored - NFRs like availability, capacity requirements, reliability, scalability, etc., must be appropriately considered while designing the tech solution or writing code.
- Not taking end-user behaviour into account - Because of how organizations are typically structured/designed, most code is written without proper knowledge of how the end-user will interact with the functionality. (Read more about Conway's law)
- Dependency on third-party or existing services (systems) in the organization is not appropriately explored. It causes delays in shipping or bugs after the product is live.
- Security considerations are often ignored while shipping products.
But there are more.
The above list contains the most common reasons leading to technical debt. But many more uncommon yet significant reasons lead to technical debt and bugs. As evident from the above list, many of the issues mentioned above can be solved by planning better before writing code or through efficient documentation and practices at the organizational levels. But humans as a species rarely do what is required/logical and often inclines to our habits and preferences.
A battle-tested template that just works
During my consulting experience, I have used a specific template to ensure that I cover most bases (you cannot cover all bases) while architecting complex technology products. Before you criticize me for creating another Engineering requirement document template, hear me out. I know most people neither have the luxury of time nor the patience to write immaculate documentation that solves future problems. But if -
- You have already suffered from losses due to your technical debt.
- You want to learn how to plan or evaluate a product requirement better
- You are empathetic towards the problem and would like to avoid it.
This template will help you with that. If you don't have time, use this template as a checklist. Just go through each section and cross off the items from the list. In most cases, a lot of sections will turn out to be not applicable.
Template link - (Notion link)
Give it a try, and let me know in the comments if it helped you. You can also mention any feedback or suggestions in the notion document as a comment (comment access is open for everyone).