5 Lessons We Learned While Scaling and Restructuring Our Engineering Teams
Being fast and nimble is important to us at Shutterstock, and one way we accomplish this is by working in small teams. This approach has yielded tremendous benefits over the years, but it comes with its own challenges: Shutterstock now has over 300 people and dozens of teams. How do we coordinate everything with so many different groups?
Here’s a bit of information about how our approach to small teams has evolved, and how we continue to change it as we grow.
The Early Days
About five years ago, we learned the value of small teams the hard way — by not having small teams. Shutterstock started with a few developers who would work on a few different projects at any given time. We followed that approach as we grew the team, until suddenly we had 10 developers working on 10 projects, and nothing was getting done.
We addressed this problem by breaking into smaller teams. Each team has a product owner, a few back-end developers, a front-end developer, a designer, and a QA engineer. The teams are meant to be independent and autonomous, capable of taking any project from idea to completion without outside help. This lets them move very quickly and stay focused on their goals.
We started with three teams: a customer team, a contributor team, and a “business value” team that was meant to focus on internal projects that bring value to the business.
The customer and contributor teams got off to a great start, and exist to this day. But the “business value” team floundered, and we learned some early important lessons about teams.
Each team needs a clear customer (or more generally, a clear target user). The team has to come to work every day excited to solve a problem for a particular audience. “Business value” was just too vague; there were many audiences within Shutterstock that needed projects, but there was no good way to prioritize one project over another. Consequently, the team was tossed from project to project, and often ended up doing things that the other teams simply didn’t want to do. After a few quarters, we decided to dissolve the team.
Each team needs a clear goal. Our customer team was living a schizophrenic existence: half its projects were focused on improving the search and download experience for our customers, the other half were about working on the signup and subscription flow to increase revenue. We addressed this by splitting the team in two. We decided that our “customer experience” team should stay focused on the primary customer experience on our site. The revenue team took over the signup and payment flow. After the split, this distinction came to feel more and more natural, and we look back on it as moving us in a better direction.
Teams need to be autonomous. As Shutterstock grew over the years, we were able to expand our offerings by creating new teams. Sometimes we’d assemble a team without making sure it had every role it needed — perhaps it would only have one developer or not have a QA engineer. We always ended up regretting this. The process only works well if the team can truly be independent and autonomous. Now we know: if we don’t have enough people to form a team, we wait until we can hire all the roles before we launch it.
Create Core Services Teams. As we added more product-oriented teams, there was a growing need to build common architectural pieces that all the teams could use. We decided several years ago to move towards a RESTful architecture, and soon many teams jointly used back-end services to support their product. But ownership of the services was problematic. If a service needed changes, it was unclear who was responsible for making that happen.
We solved that problem by introducing the latest evolution of our team strategy: core services teams. Each of these teams own one or more RESTful services, and work with the product teams to prioritize their work. Their goal is to build core infrastructure that other teams can leverage to serve their customers.
Solve the Challenge of Coordination. Today, Shutterstock has over 20 teams, all of which follow agile development practices of fast interaction and frequent customer feedback. With so many teams moving so quickly, coordination has become a challenge. This is partly addressed by returning to a core team principle: strive for autonomy and independence. We encourage teams to pursue projects that are within their power to take from idea to completion without outside help, which eliminates the need to coordinate altogether.
However, there are inevitably projects that require multiple teams to work together. In those cases, we promote four ways to improve coordination:
- Each of our teams has a planning meeting every two weeks. Anyone can attend these meetings, and we encourage teams that are working together to attend each other’s planning meetings.
- Each of our teams also has a demo every two weeks, in which they show off the work they’ve done recently. We also encourage teams that are working together to attend each other’s demos.
- We have a weekly product backlog meeting, where all our product teams share upcoming projects and discuss metrics related to recently-launched features.
- Finally, each team has a lead developer and product owner, and we give them the specific responsibility of pro-actively reaching out to other teams to discuss upcoming work.
These approaches are intentionally lightweight and simple. We rely on people’s own initiative to share their work, communicate actively with others, and work out the details themselves to address many challenges of coordination. Having a non-prescriptive process makes it clear to people that it’s their responsibility to talk to whomever they need to. So far, this approach has worked out well.
We’ll continue to evolve and adapt our team strategy as we grow. Though we’ve had some minor challenges with our approach over the years, overall it has served us very well.
This article first appeared on Shutterbits.