As Zoosk Engineering has grown throughout the years, we’ve aligned our teams in different ways based on the needs and challenges that our organization was facing at that time. One of our core values is to continually challenge the status quo by always looking for ways do our work better and faster by encouraging calculated risks in order to achieve our goals. That said, last year, we made a fundamental change in how we implemented feature development at Zoosk by moving our main feature development teams away from organizing around function to organizing around features. In this article, I’ll go over what this meant for Zoosk, the lessons learned, and the areas of continued focus from working in this style over the past year.
As with most startups, we started with a very flat engineering organization with a handful of people. As the team grew rapidly, we began to specialize and form teams in different functional areas based on the main technology platforms that we supported. This is a fairly common way to organize, and at Zoosk it looked something like this:
This worked very well for us during our high growth phase, but there were a number of pain points that became evident as we continued to scale our engineering and product management teams.
Given that most features at Zoosk require parity on all client platforms, to complete a feature across all of them, it must be scheduled through each of the respective teams from the diagram above. This would require one product manager to work with potentially seven different leads or representative PMs in order to complete a project. Just by the sheer number of touch points, it created opportunities for things to slip through the cracks and a lot of communication overhead. Also, if a project requires multiple iterations (which 99% of them do), this cost gets very high very quickly.
At Zoosk, we move very quickly, which in itself isn’t a bad thing by any means. One of the side effects of that, mainly for the teams on the backend, was that some of the teams would already be onto their next project before the previous project had fully rolled out. For example, because we used to require that API endpoints be completed before the client work had even started, it was very likely that the developers on the API team would be onto the next feature, and the previous project was out of sight, out of mind. This system definitely worked, but it made it a little harder to really appreciate and learn from a project holistically when you were already onto the next thing, and it could start to feel more like a factory.
With a functionally organized team, it naturally lends to itself to supporting career development towards being an expert in that functional area. While we do expect our engineers to specialize in a particular function to a certain extent, it’s harder to support generalists that want to get exposure in different areas of the stack. In the past, this would require an engineer switching to a different team, which is a big commitment for the individual and the company. We always support this type of career development, but because of the commitment level, it might not work for everyone. For example, if your passion is iOS development, but you are still interested in spending some time on the backend just to get more context there, moving to the API team full-time might not be where you want to focus your career.
After identifying the inefficiencies we wanted to try to improve on, and reading a lot about how other companies have organized, this is what we came up with (with the new teams highlighted in green):
This team is responsible for overseeing the processes around ownership and direction of the different platforms. This does not mean they dictate the direction of these platforms but rather facilitate how they move forward by prioritizing our engineering driven initiatives. For example, the Architecture team drives our Web Developer meetups where developers from all teams meet to talk about the different problem areas in the codebase, opportunities for improvement, and how we want to prioritize those.
At this point, we’ve been functioning in this system for about a year, and these are some of the takeaways from moving to a feature team organization.
With the new structure, we reduced the number of communication touch points from seven, down to three at the most. Also, by focusing on optimizing on the web before native clients, we’re able to optimize and decide on the main direction of the feature on web without spending as much time optimizing on native clients. There are obviously things that don’t translate from mobile web to native, but if we can figure out 80% of that, it’s still a win.
With the advent of Lotus and our improved development pipeline, client developers are able to work in parallel with backend developers for most of our feature work. This, along with a dedicated PM for each feature team, enable us to work very efficiently. It allows for developers on both sides of the stack, as well as their dedicated PM, to really own the feature holistically which wasn’t the case for everyone before.
We knew this was a tradeoff we were making when we initially moved to this system, but it became very evident when we tried to build a feature first on one of the native clients. Because the feature teams are optimized to work on the backend and client work in unison, there were a number of things that fell through the cracks as we completed the API first in a feature team, then moved onto the client work in the native teams. That said, one of the changes we do plan on making is adding dedicated backend resources to the native teams to allow them to take on more backend heavy work.
In a functional world where each team owns a platform, it’s very clear which team is in charge of constantly improving their respective platforms, tracking tech debt, and triage queues. In this new system (for us), it took awhile to get the processes just right around how the Architecture and Infrastructure team would manage the platform improvements. We still expect and encourage the developers on each feature team to participate and contribute to technical improvements on their functional platforms of expertise, but we went through a few iterations on the best way to do that.
Because of the large feature set we’ve accrued over the years, it wasn’t exactly easy or obvious how to split up those different sets between the feature teams in an intuitive way. There were a number of times when tickets would be filed to the wrong team, or we spent too much time trying to figure out exactly where the ticket should go. In a functional world, it’s a lot clearer. If there’s a bug on mobile web, it goes to the mobile web team. Correspondingly, a bug on desktop web goes to that team.
Each organizational structure has it’s pros and cons, so it really depends on the situation. It’s always hard to tell what would have happened had we not switched, but overall these changes made sense for Zoosk Engineering at the time and hopefully these main takeaways will help you as you think about your organization.