How to manage technical debt in early / mid stage startups?
Technical debt is a fact of life in companies of all shapes and sizes. In early stage or fast-growing mid-stage companies, paying off technical debt often gets pushed back in favor of launching new features and addressing pressing customer feedback. And amidst the never ending pressure of growth and go-to-market timelines, all too often companies find themselves at a precipice where the long standing technical debt suddenly becomes a hard blocker for innovation. In this post, I outline some strategies for leaders and engineering teams to cope with technical debt.
Runaway growth in technical debt is generally a good indicator that the engineering processes need some adjustments. A healthy engineering org will have built-in some (lightweight) processes to periodically invest in foundational areas and prevent too much technical debt from accruing. Here are some ideas:
- Give teams air-cover: in my experience, most engineering teams are generally quite aware and eager to work on technical debt. So the question is of prioritization rather than of motivation. Teams need to feel empowered to work on these problems and the leaders are accountable for creating the right air-cover for them. Whether it's periodic bug bashes (include PMs and designers in these!), "foundation Fridays", explicitly allocating time in OKRs or sprint plans or something else – just pick something that works for your teams and stick to it!
- Create accountability: startups, especially early-stage ones, are forever resource-constrained and are therefore constantly making trade-offs. And sometimes they choose to accumulate technical debt in favor of say a feature launch. This isn't problematic per se, where problems arise is when this decision is not communicated to all stake holders and so an explicit decision starts to look like an implicit one. This has all kinds of downstream implications: lack of clarity on follow through (i.e. what's the eventual plan to address the technical debt); lack of ownership and accountability (who is responsible for the decision and who is responsible for the cleanup); ongoing misalignment (employees wondering whether the Company is prioritizing the right things) which then fosters mistrust and more.
- Create the right incentives: process changes alone are not sufficient, your company needs to have the right culture and mindset that understands and appreciates the need and importance of paying off technical debt, and your policies need to have the right incentive structures to reinforce those norms. Specifically: create alignment and vocabulary to characterize impact and then follow through to recognize and reward said impact. There's nothing more demotivating than working on a high-impact project to reduce technical debt only to find only people who worked on shiny new features got promoted.
Whether or not you've invested in continuously paying off technical debt, you may yet find yourself at a precipice: without significant and immediate engineering investment, there would be catastrophic consequences. For instance, you may need to halt all new feature development to upgrade your software stack (e.g. due to security vulnerabilities, performance problems). Or you may have to significantly refactor the entire code-base because the current one has just become too unwieldy and risky for any new product development (e.g. this can happen when the code has become too messy and complicated for anyone to make sense of or to safely develop on).
Here are some questions leaders should be asking themselves and their teams to make sure they are making the right decisions and taking the right approach:
- Is the project well motivated? Make sure you understand the business impact of not taking this project on. Make sure everyone in the company understands what is at stake. This is necessary for alignment, to give teams air cover and to ensure everyone in the company is ready to help if needed.
- Are the options and trade-offs well-understood? Teams should try to come up with at least two or three different strategies for achieving the desired goal. For instance, a refactoring project could be done by re-writing everything from scratch, or incrementally changing the existing code-base. Ask your teams to bubble up the pros and cons of each approach, and to provide a rationale for their recommended option.
- Are the risks well-understood? Ask teams for the highest risk parts of the project. Understand if the risks are technical (e.g. teams may not be aware of all the inter-dependencies between services); staffing related (e.g. team doesn't have the right skills to take the project on, or don't even know what skills are needed). Ask teams to articulate known unknowns vs. unknown unknowns, and to present a plan to de-risk the highest risk areas (e.g. do a "prototype" for the proposed project).
- Is the project well scoped? Large, boil the ocean type projects run the risk of increasing in scope over time, or getting delayed due to new dependencies / unanticipated complications. Narrow the scope to the minimal set of things that MUST be accomplished; establish clear, objective exit criteria; establish processes to periodically review key metrics to track & communicate progress and ideally, time box the project ahead of time.
- Is the project well staffed? The best planned projects can fail without the right team to execute it. You rarely need to put all (or even most) of your engineering org to work on a single project, no matter how large. Think carefully about the right skill set and team mix needed to successfully execute the project: a strong and suitable tech lead working with a cohesive, motivated team will typically be more effective than a disorganized, all-hands-on-deck effort.
Once the project is underway, keep a tight check on the execution: meet as frequently as needed to get status; build alignment; communicate progress / risks to all stake-holders. And most importantly, once the project concludes, make sure to celebrate; recognize and reward those who contributed; and take time to do retrospective to share any learnings with the whole company.
In the next post, I'll discuss how to operationalize managing technical debt at scale.