Have you ever worked for a new startup with just a couple of developers? It’s pretty amazing, for a while.
You know everything about the business domain. You know the whole codebase because you mostly wrote it. There’s no decision you can’t make yourself. You’ve been spending time with the same two people, so you know how they think and how to best communicate with them.
It feels like the team is flying. New features are shipped to customers every week.
Fast-forward five years. Your company has been successful, but the complexity has grown significantly. There are product areas that no one on the current team has ever touched. The business domain has expanded in every direction imaginable, and there’s not a single person who can talk about all the details regarding every corner of the product. You’ve never met 80% of the employees. You wouldn’t know who to ask if you need help with an obscure technical question.
It’s difficult to feel ownership of something supposedly owned by a hundred people.
Teams split an overly complex domain into smaller pieces, allowing a group of people to feel a higher connection with their objectives, owned codebases, and their teammates.
To some degree, teams are silos. When you create a team, you’re saying it’s important for this group of people to be in sync with each other, but they don’t necessarily have to be quite as in sync with others. Silos are usually mentioned negatively, but without some intentional and well-designed siloing, people would get constantly overwhelmed and zone out with topics that they need to stay on top of.
A couple of years ago, it was common to split into a “frontend team” and a “backend team.” This way, backend developers would not need to be bothered with dirty details of the frontend, and vice versa. You would also get to work with people whose skillsets you understand.
This structure optimizes for learning about your craft (either frontend or backend), and collaboration within your team might feel easier.
Unfortunately, this setup fundamentally limits a team’s ownership of their area. Since practically all new functionality will involve changes in frontend and backend, teams cannot necessarily control their backlogs. Someone outside the team needs to manage the projects, asking teams to deliver tasks.
This arrangement also means that the software lifecycle is easy to ignore. If the team is just a puppet for someone else, who will take care of technical debt or proactively invest in some platform work? The team will likely ask for time for their priorities, and usually, those requests won’t be entertained.
A similarly problematic approach is to have multiple teams working from a shared backlog as “feature teams.” It works for people prioritizing that shared backlog since they have more control over what gets done.
From the team’s standpoint, it has many of the same issues: the software lifecycle is forgotten, the team doesn’t have real ownership of the codebases, and they always have to learn new product areas when starting to work on a feature.
Maybe most importantly, every team has to deal with the full complexity. The team split fails to reduce the cognitive load experienced by the teams.
Organization design is about dealing with tradeoffs. Since every communication path cannot be the strongest one, you have to choose what you prioritize over other things.
In most cases, you’re building software for a business, and there lies your answer: your ability to drive business outcomes is the No. 1 priority. Building software needs to be a good investment.
A team is most likely to drive business outcomes when it can make good decisions about its direction, iterate quickly, and is not slowed down by dependencies.
Teams are empowered to make these decisions when they have clear objectives and have a specific area to work within. Once those two pieces are in place, it’s less important to know the exact features in the roadmap. When the team learns something new, they can change the roadmap. The team can choose to invest in the technical architecture to move faster.
Designing a software engineering organization is a multi-variable optimization problem where you try to balance the following considerations:
These four parameters define the team’s boundary of ownership.
There is no simple algorithm for creating your teams — you’ll have to try different combinations to see how they might work. One approach to consider is a simple spreadsheet that contains all of these dimensions; you move cells between the teams to see how balanced the team would be. Sometimes, you’ll move a developer together with a feature they have worked on to make it easier for the receiving team to accept new responsibilities.
You’re going to evaluate a set of tradeoffs for each team, with things like:
As a rule of thumb, these teams will be relatively full-stack, combining skills from different parts of the technology stack. You’ll likely also want to cover skills like design, data science, infrastructure, and product expertise.
Oftentimes, you’ll have to compromise. For example:
Most commonly, all software engineers report to a team lead or an engineering manager who is familiar with their day-to-day work.
There are a few different alternatives for sharing the management responsibilities in a team:
These are tradeoffs you need to make based on the kind of management talent you have available.
Responsibilities like facilitating daily standups or team retrospectives can be rotated among team members. Having someone other than the team’s manager facilitate meetings levels the playing field for conversations.
Product managers and designers typically report to someone in the product organization, but they are usually placed in engineering teams and participate in their teams’ rituals. This helps them build consistency for the product across different teams, and these roles have an inherently high amount of collaboration.
Team Topologies introduces stream-aligned teams, enabling teams, complex subsystem teams, and platform teams.
I like simplifying the model a bit: product teams are the vertical slices of your organization, and platform teams are the horizontal slices. Their communication patterns are quite well-established. Sometimes, you will need special teams where you need to design their roles case-by-case.
Most of your teams will be product teams, as defined in Empowered by Marty Cagan. It’s similar to stream-aligned teams in Team Topologies. They will own a slice of your business domain and can make decisions and deliver features independently with minimal dependencies.
These teams will allow you to split a complex domain between multiple teams, and they will maximize the speed of delivering business outcomes.
A big part of your organization’s growth will simply involve deciding where to invest more and carving out responsibilities for a new team in that domain.
For an imaginary food delivery business, you might start the organization design by considering the three core audiences it serves: consumers, restaurants, and couriers.
Each team has a different persona they listen to and whose problems they’re trying to solve. Prioritizing becomes easier when they know where to source their feedback.
In practice, each persona also uses a different software product. Restaurants manage their menus from one application, couriers navigate to their destination with another, and consumers order food from a third application.
In the background, the software architecture supports scaling as well. The service that routes couriers to their destination is decoupled from the rest of the business.
Each one of these teams can be split into smaller teams. Once you’re growing the organization enough (because, presumably, you’re trying to move very quickly), you’ll discover that each team owns a relatively small part of the puzzle.
At that point, some of the previous tradeoffs might tip over — for example, it’s perfectly normal to have technology-specific teams working on a single, very valuable codebase. Team Topologies have the concept of “Complex subsystem teams,” which could be a microservice with many scalability needs.
Our organization at Swarmia is built to deliver a B2B SaaS product to help software development teams in the engineering effectiveness space.
For our business, we’ve identified the following important guiding principles:
The business and what’s unique about us sets the frame for organization design. This led to us assigning the following outcomes, features, people, and architecture elements:
Team: Core (Dumbo)
Team: Developers (Ballmer)
Team: Growth (Groot)
Team: Platform (Yoshi)
Once you have a few product teams, you will discover that they sometimes act like independent companies. This is by design, but some standardization would benefit the teams.
No matter how important an objective is for your company, you can’t suddenly assign a thousand engineers to work on it and expect results. This is why Big Tech often has 50%+ of their engineers in platform teams with the objective of making the rest of the engineers move faster.
The idea with platforms is that you should get really good at whatever your company is doing a lot of. Sometimes, it’s the more obvious answers, like deploying code to production — yes, you should have a CI/CD pipeline. These platforms could also come in the form of:
Thus, platforms give leverage to teams and help your organization move faster.
As the organization continues to scale, certain areas that don’t fit neatly into existing product or platform team structures will emerge. In these cases, you may have to get creative and design another type of team.
Product and platform teams have fairly simple patterns of ownership and communication needs. At some point, you’ll want to make a tradeoff that doesn’t perfectly fit these models, and that’s fine — as long as you recognize the tradeoff you’re making.
This could be teams like:
Your organization might not need these types of teams right now, but having it in your vocabulary can be helpful when a team is venturing into this direction and feels frustrated by the collaboration overhead. There’s no escaping this type of work, yet it can be very impactful for the business.
Congratulations, you have mapped out the organization you currently want to build. Now what?
As an engineering leader, you have a couple of responsibilities that no one else in the organization is likely to do for you:
Traditionally, product investments were made far from the engineering teams. The company would decide to fund “projects” and “features,” often without much detail about the implementation options or the competing priorities — and often with no idea whether the customers really needed it.
With empowered product teams, your main unit of investment is a team. You fund a team to work on an objective, and they’ll prioritize features and other types of work to get there. If you want to move faster towards a goal, you can sometimes choose to invest in more than one team — but you might need to pace your investment over a longer period.
Some companies take self-organization too far, treating goal-setting as a team-only activity. While it ’s a good idea for the team to drive the goal-setting process, as an engineering leader, you can support the team in choosing the right objectives. You’ll have more context from all the other teams and must ensure the team objectives collectively map to your strategy.
As a leader, you’ll want to track your company objectives and all the projects that are contributing to them. Ideally, the company objectives are in priority order (or there’s just one of them!) so that each team knows where their help is most needed. You can follow whether the teams are constantly getting work done in their areas, or if they got dragged to something else.
These other priorities are sometimes easier to see from a team’s investment balance. The Balance Framework helps you understand how much each team is spending on keeping the lights on, building new things, improving existing features, or improving productivity.
For example, a team that’s spending 80% of their time just keeping the lights on can’t complete many new product features.
One of the main goals of your organization structure is to minimize dependencies. Product teams own domains and components in their area, and platform teams serve other teams through clearly defined application interfaces.
Unfortunately, if your team truly pursues its objectives rather than trying to stay in its lane, eventually, it will need to do something that depends on another team.
Dependencies are the problem that will break your plans. A project might only have two weeks of work, but it could take 6 months of calendar time if you need to convince other teams to change their priorities.
Historically, companies have attempted rituals like “Scrum of Scrums” to coordinate between the teams. Some organizations align sprint start dates between the teams to get them “marching” in unison. The real issues are rarely uncovered in a “Scrum of Scrums” meeting because updates are shared at a high level, and the real problems are in the details.
The main strategies for dealing with dependencies are:
Hopefully, these guidelines will help you recognize what to consider when building a software engineering organization.
Ultimately, it’s always a tradeoff, and the real world is full of nasty details (so you have one designer for the 100 developers?).
Consider sharing this blog post with your engineers so that they know how you think about building the organization because many of the details will come from your developers directly.
Subscribe to our newsletter
Get the latest product updates and #goodreads delivered to your inbox once a month.