How to Structure Engineering Teams 🏯
A thorough guide about principles, roles, growth stages, and plenty of resources.
Since I the very beginning of my newsletter journey, I have written a lot about scaling and organizing engineering teams.
That’s because this is a core part of my work experience — as CTO of an early stage startup first, and manager of a high-growth, larger company later.
Articles I have written usually cover specific aspects — from the need for managers, to how communication changes with growth.
So, today I am publishing a comprehensive Guide 📖 that puts together everything I said about this topic in a full framework that you can use at work. It will be a way longer, more in-depth and more researched article than usual!
For this reason, you will find a paywall at about 🔒 50% of the article. If you like the first part, consider joining the full plan to support our work!
Here is what we’ll cover today:
🔭 Principles — what makes a team good? Mental models for creating effective engineering teams.
🎽 Roles — what are the core roles and responsibilities you should assign?
⏳ Teams longevity — how long should a team last? What are teams *really* about?
🪴 Growth Stages — how does structure change through the various growth stages of a company?
🤔 Unconventional Teams — stories and tactics of companies that do things differently.
💬 Community Stories — two real-world team structures from the Refactoring community.
📌 Takeaways — summarizing this long guide into four main actionable points.
Let’s dive in!
🔭 Principles
Within each company, there are groups of people who are more likely to work together than others. Creating teams simply means defining processes that make it easier for such people to interact on a regular basis.
Team structure shapes how communication happens, which, in turn, shapes how software gets made. As by Conway’s law 👇
Any organization that designs a system (defined broadly) will produce a design whose structure is a copy of the organization's communication structure.
— Melvin Conway, circa 1967
The main takeaway of Conway’s law is that if you create a good team organization, software will largely take care of itself.
But what makes a team organization good?
I have a personal heuristic that looks at three things: Autonomy, Cognitive Load, and Responsibilities.
1) Autonomy 🏃♂️
You want teams to be autonomous.
What makes a small startup go fast is how cohesive and nimble the team is — people can work quick and without overhead. In a larger org, you most likely want to replicate this by creating many of such teams.
2) Cognitive Load 🧠
A good team should own an amount of software that can fit in their head.
Engineers and teams are able to bring the most value when they sustain the right amount of cognitive load for their work: not too much, not too little.
Also, not all cognitive load is created equal: you should spend most of your cognitive budget on domain and business knowledge, which creates actual value, and minimize what comes from extraneous stuff like bad DX and convoluted tech.
3) Responsibilities 👑
On good teams, all the bases are covered. You know exactly who is responsible for what, and people have the right skills for the job.
In a modern software team there are three main responsibilities:
🎨 Product — owning the roadmap, feature requirements, and communication with customers & stakeholders. Creating alignment and removing obstacles from the way of the team.
🔨 Tech — owning the technical direction of the product. Making design decisions and guiding the development.
🌱 People — taking care of people’s growth and wellbeing. Working on processes, hiring, and career tracks.
Should these responsibilities belong to separate people or can they partially conflate on the same ones?
It’s… complicated.
Let’s talk about roles 👇
🎽 Roles
If you had to assign separate roles to the three main responsibilities, these would be Product Managers, Tech Leads, and Engineering Managers.
In many orgs, though, you can find hybrid roles where people wear more than one hat. E.g. an EM who also acts as TL, or a PM to whom engineers report to.
In many cases, this is fine! For various reasons:
There are big overlaps between these roles anyway.
Your scale might make any of these not a full time job.
You may have people who are able to pull this off (they exist!).
Especially if you don’t work in a big corp, this is natural and even healthy. So, if you are unsure about how to assign these duties, here are some angles you can consider:
1) Autonomy + Cognitive Load 🧘
Back to the initial principles, which are useful here, too. You should find a balance where:
People own meaningful work → Autonomy
People are not overwhelmed → Cognitive Load
Some examples where this thinking is useful:
You can make engineers own individual features instead of creating a TL role, to foster more autonomy and ownership.
You may start with a hybrid IC + manager role as long as the team is small, and branch out into a full-time manager role when duties like hiring and careers make the load excessive.
2) Consistency 🪢
As your company grows, hybrid roles become tricky because it’s harder to ensure consistency across the org. Sure, you may have a star IC who is also able to perform as an EM — but do you have one of them on all teams?
Building coherence around how roles are performed is important for many reasons:
Facilitate rotation — so that people can switch teams with ease.
Enable careers — people should know what is needed from their role to perform well across the company, not just on their team.
Standardize hiring — if team A hires a senior engineer, this should match the senior engineer’s definition of team B and team C.
⏳ Teams longevity
An underrated factor to consider is how long the life of a team is. How long are people going to work together on the same thing?
This question is relevant because the main objection to creating separate, independent teams is that you may not be able to identify stable product areas on which to allocate fixed resources.
In fact, there are two main configurations through which people usually ship stuff:
🎯 Feature Teams — teams assembled to deliver a specific initiative. Will be dismantled afterwards.
🎽 Durable Teams — teams accountable for a long-lived product / business area.
Let’s see the consequences of going with one or the other (or anything in between) from three main angles:
1) Resource Allocation 🍱
Flexible vs Fixed
Feature teams have flexible resource allocation. They can be scoped based on the project they have to tackle and the velocity you want to achieve.
Durable Teams, in contrast, have fixed (or slow-changing) allocation.
The upsides of flexibility are obvious: you allocate resources precisely for your goals. This is crucial in small companies, where people may wear many hats and projects have overlapping resources.
This is also good in fast-moving environments, such as startups, where it's tricky to identify stable areas of allocation.
The downside of flexibility is that it brings management overhead. If every initiative requires negotiation on how resources should be organized, it may become a big tax fast.