Looking across the startup landscape of 2016, technical debt remains a massive concern for many companies. When velocity declines, not only does that demoralize the team, but it also dramatically hinders the company’s ability to grow and to capture new opportunity.
There has been considerable thought on preventing this from a technical standpoint (independently scalable microservices being the latest trend) but I haven’t seen as much output from a product manager’s perspective.
Below are six approaches for product managers to prevent and address technical debt.
1. Test product concepts the right way. One of the biggest costs of the Lean Startup movement has been the accumulation of “test” code that, unfortunately, ended up becoming a full-on, hacked-together feature. Many concepts are great to test with code, but take a close look at what you are testing and ask yourself if you can accomplish this with something even leaner (such as a clickable prototype). Not only is this a FASTER way to test in many scenarios, but it also allows you to create numerous variations without accumulating technical debt along the way.
2. Review unused features on a monthly basis. I like to look at the analytics each month to better understand which features aren’t being utilized by the user. Reviewing these to assess whether or not they are right for the product can wipe out huge amounts of code. Nothing makes great engineers happier than deleting hundreds of lines of garbage code. And the beautiful thing about Github is that the code is always recoverable. So go ahead, delete away!
3. Anticipate scaling bottlenecks. Even systems with beautifully scalable microservices will hit bottlenecks (you’ll especially see the network getting clogged as these services talk to each other). As product managers, we must know where the limits of the system lie so that we can track and prioritize addressing them before they become major issues. Slow page response times kill engagement more than missing features.
To get an idea of this, run load tests on a few key scenarios and identify the inflection points. As your metrics start to track towards those points, make sure you address them appropriately.
I interviewed Greg Pass (former Twitter VP of Engineering) for my Cornell Underground Entrepreneurs group a while back and he shared some advice on scaling that really stuck with me. Rather than trying to wholesale “fix once and for all” the scaling challenges you anticipate, simply identify the next bottleneck and solve that. And then repeat. Otherwise, you’re spending time on areas of the product that may never make a difference for the users. Fred Wilson also wrote about learning this critical concept from Greg:
He taught me that you can’t build something that will never break. You have to constantly be rebuilding parts of the system and you need to have the data and processes to know which parts to focus on at what time.
4. Be clear about urgency with the engineering team. Is this a “get it in by X date no matter what” scenario? If so, communicate that urgency to the team and explain the drivers (e.g. a key sale depends on this, VC expectations for closing fundraising, etc). Not everyone will agree, but “just do it now” is the most discouraging thing you can tell an engineer. And then add another story to the queue to clean up the code and make sure it’s properly tested! You must defend the quality.
5. Be creative about how you solve classic challenges. One of my favorite approaches to removing technical debt is to stop coding emails in your backend. Use Segment to send events to Customer.io or Intercom and let those drive your transactional emails. Then, you also have the power to send behavioral emails (e.g. sign up flow drop-off, cart abandon, long-time-no-see, etc.) which are huge for driving engagement. I guarantee no engineer will miss maintaining the HTML code for your emails.
6. Double the time allocated to stories that touch code with technical debt. A less dramatic approach that nicely fits with the agile cadence is to simply double (or sometimes triple) the estimate for each story that touches “bad” code. This ensures that your engineers have additional time while keeping it timeboxed. You can address the issue without having to go through an elaborate prioritization process. (Thanks to Payton Miller for reminding me of this one!)