I've been working at Buffer since 2014, and even before I joined, I was always impressed by the Buffer team's product and engineering culture: how quick they shipped improvements and how close everyone was to the users (not uncommon to see engineers responding to comments on Twitter!).
I found that "can-do" attitude inspiring and contagious, and it's amazing when things click that way. Of course, back when I joined, we were a team of 24 people; we all wore many hats and had no managers.
As we grew, we started embracing the creation of team structures and processes to support us better and manage that growth. But of course, scaling collaboration while maintaining speed is an art in and of itself, and friction points started to appear: projects would run into bottlenecks more often, and teams would block each other. Since it would take longer to release features, we'd try to get them "right" by spending more time crafting the specifications of what we tried to build, but of course, the larger the projects, the longer it took to deliver them.
We were stuck in a self-amplifying loop: if it took months to build something, it made it extremely difficult to fast-follow and iterate on it because we would also have other priorities to attend! This just kept reinforcing the need to do more and better and kept creating more pressure to "get it right."
Last year, we realized we wanted to change certain habits and dynamics at Buffer to return to those early days of shipping frequently: the more regularly we ship, the easier to manage those changes are (because they are smaller). It feels safer even if that thing we're shipping fails - creating greater psychological safety for our team. It was clear: we wanted to become builders again and embrace our entrepreneurial spirit and culture of defaulting to action.
The metrics that help us define builder mode
How will we know we're in builder mode? That we are moving faster, shipping more often, and tightening our feedback loops with our customers? Some metrics are helpful to guide us in this journey: cycle time, pull request throughput, and defect rate. Here's some context on what those metrics mean, and how we measure them:
Since we want to decrease our time-to-market, we want to measure how fast and how often we deliver value to our users. Cycle time is, for us, the time between we start working on a feature or improvement (the first change we do in the codebase for that) to when a Pull Request with the changes is merged and released to production.
Pull request throughput
Pull requests are the artifacts we generate as developers to begin the process of merging new code changes with the current code that's running in production.
We can think of each pull request as a unit of work that provides value (e.g. a new feature, a bug fix, or any other codebase improvement). That's why a total count of pull requests merged (and deployed to production) can be a proxy for value delivered.
Of course, moving faster doesn't improve anything if it means we're shipping more defects and bugs to our customers!
Defect rate acts as a control metric for us, where we measure how many of the code changes we perform are addressing bugs that were introduced in past changes.
Dynamics we have implemented to drive this engineering mindset change
Just as habits are vital for shaping our identity as individuals, they are fundamental for evolving our mindset and culture as a company.
Knowing what we wanted to achieve and how to measure it, we started thinking about new dynamics that, as we adopt them, help us build our identity as builders. Also, we kept our eyes open for existing habits that were getting in the way and preventing us from getting to this next level.
Customer engineering days
A crucial component for any builder is to be in touch with their customers: interacting directly with our customers is key to gaining insights into the questions they ask, the needs they have, and the pain points that are feeling in our systems.
With customer engineering days, we have each engineering team allocating one engineer each cycle pairing with an advocate for a day answering tickets in the inbox and fixing quick wins together. This is a great opportunity for engineers to ask our customer advocates questions about our customers, features, and products, and for advocates to share their experiences and provide some great customer insights!
Removing blocking Pull Requests as much as possible
As we embrace a culture of moving faster, one of the first things that caught my attention was the review process to integrate changes into production: some teams would have an enforced rule that required another developer to review their code before pushing a change live. Industry benchmarks and research have shown surprising results: approval processes for code changes are not correlated with software delivery performance.
We want to remove gatekeeping for changes, promote ownership and empower people to remain in a flow state, so teams have started shifting away from defaulting to open Pull Requests and wait for approval, and use a hybrid method named "Ship/Show/Ask":
- Ship means just that! No need to ask for a review, just make the change and deploy it to production.
- Show is great for getting asynchronous feedback, or sharing some new patterns and learnings with the team, but not waiting to get the approval before shipping to production.
- Ask is the traditional approach in which you require a code review before merging and shipping to production.
Being clear that there are alternatives and different approaches for different situations means that teams can figure out which balance to strike, and see if they're in "ask mode" too much when they could nudge more towards "ship" or "show".
Of course, if we were to just focus on the previous practices, it would feel like we're just asking the teams to do more and faster work. These goals and practices are for us to challenge and improve how we work, and not how much we work!
A key component to ensure that, and a major contributor to becoming a higher performing team, is working smaller: if we decompose our work into features that allow for rapid development instead of bigger, more complex projects that get released infrequently.
For that, the engineering teams embrace the usage of feature flips (also named feature toggles) as a way to deploy new features that are still under development to production without negatively impacting the user experience. This gets rid of big releases that contain many changes, and instead, we can release new features to our users when we've already experienced them in production.
Working in smaller batches generates greater psychological safety for our engineers, since the risk of deploying breaking changes that impact everyone is greatly reduced.
Engineering managers' role shift to become builders, too
While the role of the engineering manager on the different teams has been focused primarily on people management, engineer career growth, and coordinating ways of working, their key responsibility is to ensure that our teams deliver value by building our product and teams in a way that aligns with both our product and technical goals.
So to truly lead with that builders' mindset, our engineering managers need to become builders too! We've redefined the role of the engineering manager and we now aim for them to spend at least 25% of their time being hands-on in the team. That "hands-on" can take many shapes, such as:
- Diving into data analysis for a new feature launch.
- Working on non-critical tasks.
- QA'ing new features.
- Engaging with customers.
This gives them an even better context and insights into the technical decisions and tradeoffs that their teams face and creates a shared sense of ownership across the team in that we all contribute in our own way to release more often.
The results: Have we adopted the builder mindset?
We started on this journey of mindset change 9 months ago and it's been an incredible path of alignment between teams: the number of features and improvements we've shipped in the last few months is a reflection of all these changes. We keep asking ourselves "how can we ship the next thing sooner, and with greater quality?". We feel there is a change in motivation and energy.
Now, if we go back at the metrics I shared earlier in this post, we can see that:
- Cycle time has gone down dramatically: from 94.8 hours in average in 2021 to 55 hours in 2022 so far.
- PR throughput has increased: 4155 Pull Requests deployed in 2021 compared to 3687 deployed in 2022 so far (1816 more Pull Requests than H2 2021!).
- The defect rate has gone down: from 18 percent of the time working on fixing defects in 2021 to 16 percent in 2022 so far.
This means that the engineering team is indeed releasing faster and more often and that quality is not at odds with delivery speed.
There are some great technical projects underway that will speed the whole engineering team way more in the second half of the year, so we're just getting started! Are there any habits your team has been doing that have helped them increase their shipping pace, and get closer to your customers? As we continue on this path to becoming builders, I'm excited to keep sharing our learnings and progress along the way.
Feel free to reach out to me on Twitter at @msanromanv to share your experiences!