How to organize software development teams?
Over the years I have come across two predominant ways to organize software development teams. One is functionally oriented, in which software teams are organized in a manner similar to the product’s architecture. Another model is one in which teams are organized around features. Under this model, teams are responsible for the development of one ore more features that can cut across the entire product’s architecture.
Consider the case of SoftCo, a fast growing software startup. SoftCo’s product architecture is illustrated below. The product is comprised of three major components: a web front-end, a set of middleware services and a backend layer. Pretty simple.
If SoftCo were to organize its software development teams to match its product architecture then it would have three teams: a front-end team, a middleware team and a backend team. Conway’s Law in action. Alternatively, SoftCo’s teams can be organized around features as illustrated in the diagram below.
Under the feature oriented model, SoftCo would have three software development teams. One team will be responsible for the development of Feature-A - the “Feature-A Team”, another for Feature-B and so forth. Note that the scope of the teams, meaning what parts of the product architecture they work on, is dependent on the features scope. Teams A and B will have to work on all aspects of the product, while Team-C will not work on the front-end. This model is similar to Spotify’s Squads.
There are several tradeoffs to be considered when evaluating these two models. However, my preference is to default to the feature oriented model. This should hopefully become evident through the rest of this post.
The first, and arguably the most important reason why I prefer feature-oriented teams is because it is easier to plan and coordinate work. Since there is only one team that is responsible for the delivery of a feature, then this makes tracking and planning much easier than having to coordinate feature development across multiple teams. The problem of cross-team collaboration becomes excessively acute in larger organizations where you might have to coordinate, align and plan for features with dependent teams months in advance.
Another important reason in favor of the feature-oriented model is that it can result in happier and highly motivated teams. It’s far more powerful and motivating to own and build an entire feature versus delivering an API that might one day be consumed by another team for a customer-facing feature. I also believe that having multi-disciplinary teams, which you will need in feature-oriented structure, exposes teams to different parts of the software stack. The team members working on Feature-A will have to work on all parts of SoftCo’s product, from React to SQL. That exposes the team to different parts of the software stack, which might be useful for personal growth and development. On the flip-side, it is somewhat difficult to develop deep expertise in one area under this model. Consider an engineer who wants to specialize in back-end software development. In this case, the functional structure is clearly superior as she can decide to work on the back-end team and only that team.
A subtle consequence of feature-oriented teams being responsible for entire features and therefore working on various parts of the software stack is risk management. Consider the case of Bob, a senior software developer. Bob single-handedly built SoftCo’s entire backend over a period of 3 months. No one other than Bob knows how the backend works. Bob goes on a 6 week long vacation during which every software team that needed backend work grounds to a halt mostly in fear of diving into an alien and critical code-base. A feature-oriented structure de-risks this single point of failure, because multiple software developers will have to work on the back-end. You should not find yourself in the situation where you have Bob’s in your organization. That is true regardless of how you structure your software teams.
Perhaps the hardest aspect of getting the feature-oriented model to work well is product design and architecture. Under a functional oriented approach, each functional area of the product is owned by a team, who presumably will spend the appropriate time designing and building each of these areas. However, with a feature approach, several teams might be simultaneously making changes to parts of the products. This makes settling on a coherent architecture and design challenging. It’s not an insurmountable challenge, and can be addressed by having a robust design review process. A team that is about to embark on the development of a new feature should start that process with a design review. This process requires a peer review of the team’s proposed design. The peer review is typically conducted by other senior engineers and software architects/CTO. This process helps ensure that the team has thought of the various tradeoffs when designing their feature, before implementing it, and that the design is maintainable for future product development. Regardless of how you structure your software teams, having a culture of robust design reviews is a must.
I mentioned earlier that I default to the feature-oriented, or squad, model by default. That doesn’t mean that I use that 100% of the time. There are times when organizing teams around functional areas is the right approach. That can be especially true in the very days of product development where you have nothing to start building on. There is no backend, middleware or front-end. Bootstrapping a product with a functional approach is a better approach. Later on you can move to a feature-oriented approach.