Thoughts on Product Lifecycle

When we invest in a new company, I spend the first few weeks getting to know the team to understand their current challenges and help where I can. A common topic is that of the product lifecycle, everything from defining a north star, to developing a written roadmap, to executing and delivering a successful product. Last month, I wrote down some of the key points that emerged during those discussions. In particular, I wanted to highlight some of the most salient points of tension.


Customer-Specific Requests

Some backlogs have many issues/features labeled with a customer name. While I think customers should be a strong force in driving the roadmap, my recommendation is to always add a process of interpretation and generalization to customer feedback. Rather than "solving problem y for customer x", it's always better to determine if other customers have problems similar to y and then define a feature Y' which will solve the more general concern. Sometimes it's not obvious how this problem applies to other customers - that's an opportunity to pause and give yourself more time to figure out a pattern. One possibility is that the request was the customer playing Product Management; that's to say they have ideas without evidence. A second scenario is that the problem is real, but your PM failed to fully grasp its true nature, thus making it difficult to compare across customers. Finally, this customer might be ahead of the curve and be 100% on point, but in my experience this third case is rare and tends to often be associated with the same handful of savvy customers. Having a lot of customer-specific requests tends to be correlated with long onboarding times, and is common among companies threading the line between services (undesired) and pure software business models.


"Code Monkey" Paradox

Engineers dread the idea of becoming code monkeys, a scheme where they are told exactly what to do and are stripped from all creativity. In contrast, each time a deliverable requires revision, the same engineers often complain that the original specification wasn't sufficiently robust. Perhaps counterintuitively, by increasing the granularity and detail of requests coming to engineering, the team adapts to become progressively worse at interpreting any gaps in a product specification. This creates a negative feedback loop. As more detail is pushed from execution to planning, the makers in the team will become less intuitive, feel less ownership, and deliver fewer results. Eventually this starts affecting not only the behavior of the team, but a self-selection process where the more independent engineers will quit, accelerating the demise. The solution is actually to expect developers to understand the product and to feel accountable for the outcomes of their projects. Rather than providing a detailed recipe for how to construct a solution, Product should focus on a high level description and put emphasis on what is the problem that needs to be solved and why it is important.


Code Reliability vs QA

Having a strong QA function often produces a negative feedback loop which leads to worse code over time. The best teams make engineers responsible for the quality of their code. A team that has low tolerance and high accountability for bugs will innovate to eliminate root causes. There will always be bugs that make it into production, but when issues are investigated and root-caused, and permanent mitigations are implemented, the same bug will never happen twice. For example, if a developer writes a DELETE query that doesn't have enough constraints, causing a mess in production, the same developer can add a clause to their query engine that only executes DELETES if they will affect fewer than 10 records, or throw an error otherwise. Segmenting bugs in different ways is very helpful in determining root causes. Are bugs typically caused by a particular person or team? Are issues usually within a particular service or part of the codebase? Is buggy code more frequently deployed on Fridays/Weekends? Each segment will reveal a pattern and each pattern can be mitigated with a mechanism or automation. Finally, take the time to perform investigations of non-trivial issues and share the results of these root-cause analyses and long-term mitigations with the team. Mistakes will be made, but the number can be reduced if the entire team learns from a single person's mistake. Side note: whenever possible, have local machines and staging servers use data identical (or very similar) to production, even if it requires extra workarounds to remain compliant with privacy regulations.


Effectiveness > Efficiency (Thematic Roadmaps)

It's convenient to think of software developers as a fungible resource that can accomplish perfectly partitioned tasks and operate with consistent velocity and predictable timelines. In reality, people are significantly more effective when they can focus on one problem at a time, and have enough room to dive deep into the subject to develop innovative solutions. In other words, an effective team tends to be less efficient with task allocation, but they are more likely to deliver on your goals. An efficient team will look productive on paper, but in retrospect will tend to accomplish less. My recommendation is to avoid assigning disparate tasks to developers and instead put time to group several tasks into 2-4 week long projects centered around a single problem. Doing this will often result in the team not working on the top 10 tasks, but instead building themes around the top 3 and finding other issues deeper in the backlog that align with those. The genius of a product manager is to be able to elegantly pull tasks together into a compelling story that guides and motivates engineers to achieve something that goes beyond the sum of tasks. Ideally, each of these initiatives should be associated with a goal (site speed, conversion rate, NPS score) and the developer will measure their own success not only on completing designated tasks, but also on achieving desired business outcomes. 


Aesthetics != Design

People often conflate the general concept of design with the specific aspect of aesthetics. The most important design consideration for the vast majority of products is that of functional design. Namely, whether the product has the right ergonomics to enable the user to navigate the required workflows as flawlessly and painlessly as possible. Certainly, we want our product to have a look ‘n feel in accordance with the ages. But that can be easily achieved by leaning on existing assets, either open source or for sale. When it comes to software, in most cases, aiming for a unique aesthetic will have minimal business benefit at best, and negative implications at worst. Developing a novel design aesthetic will require iteration, which will eat away cycles of front end development, user testing, etc. Aesthetics are also very subjective, so if a team has designer churn, the application can quickly become Frankensteinian. On the other hand, by leaning on a mature design system like Material, immediately empowers developers with a vast library of components for various front-end stacks. Furthermore, starting with a well established aesthetic doesn’t prevent us from layering personality on top, such as the color palette, typography, white spaces, and custom elements.