The concept of Team Topologies, as depicted in the book written by Matthew Skelton and Manuel Pais, is getting worldwide attention. The focus on team structure and purpose is opening interesting discussions and many organizations are adopting the model as a reference for their development teams organization.
At the same time, Domain-Driven Design practitioners have a sense of deja-vu, since the problem space seems to be overlapping with some of the advanced concepts of Context Mapping. This my attempt to see the best of both worlds, and the pros and cons of the different approaches.
The problem space is largely uncharted territory
Pais and Skelton clearly hit a nerve with their book. Most organization grow organically, growing in size under the pressure of a growing backlog. Teams growing in size will have to be split and competences will become more narrowed and specialized. However, the criteria diving the splitting (even if not many) have been debated endlessly and whichever is the adopted decision - cut around business capabilities vs cut around technical skills - the outcome is never perfect, leaving the decision-makers with a feeling of maybe the other approach could have been better...
To make matters worse, every organization places the responsibility of sizing and structuring teams in different hands: is this a team leader responsibility, or head of development? Or CTO maybe? Do we need a specific role for that? Do we always need to escalate to the ecosystem level or is the collaboration between teams just a local issue?
Have you been spotified?
This lack of reference models also explains the popularity of the Spotify Model: an organization that experimented on a different model for team structure and collaboration quickly became a source of inspiration, with a lot of unintended consequences. As it happen with lean and Toyota, others followed the model, without paying too much attention to the ingredients that made that model viable in that specific context.
In short, most nontrivial software development organizations experience some kind of friction in this space. Collaboration between software teams is one of the key fundamental traits of successful companies, but frictionless collaboration seems to be a chimera so it's not a surprise if IT professionals are seeking for guidance.
Team Topologies categorizations
Team Topologies describes four team types:
- Stream Aligned Team focused on a specific business capability, ideally cross-functional;
- Platform Team providing common services to other teams;
- Complicated Subsystem Team a team with high specialization, and specific knowledge about one portion of the system;
- Enabling Team a team of experts, mentoring and helping other team to evolve and improve.
While these concepts are not new - they stem out of observation of many different ecosystems - it is interesting to see that they provide a vocabulary and some reference model. You may want to consider this list of archetypes as attractors for what a good team should be, but also note that they're only four!
Some weird things your organization is doing aren't listed here, maybe for a good reason. These are reference implementations for teams that work well.
Three interaction modes
In terms of relationship between teams, three patterns are described:
- Collaboration when two teams are working closely to a common goal;
- X - as a service when there is contact in terms of usage, but little specific collaboration;
- Facilitation when a team is helping another one to get rid of impediments.
Once again the list is short (so patterns which are not listed are interesting), and the patterns are attractors: failing to define the type of engagement will leave space to ambiguities that will turn into frictions and delays.
Context Mapping patterns
Strategic Domain-Driven Design offers an interesting point of view on the same problem space, but with different constructs.
There is little explicit reference to teams but the focus is mostly on Bounded Contexts under the assumption that in a mid-sized software organization there will be a close mapping between the two concepts.
Are Bounded Contexts teams?
No, bounded contexts are defined like the limit of applicability of a given model. But the sophisticated domain understanding, which is a fundamental ingredient of domain-driven design, is only possible if a single team is responsible for a given portion of the model, with connections on the entire socio-technical stack (talking to business representatives, writing and testing the code, interacting with users, and so on).
There's some well accepted wisdom in the DDD community about it, let's make it explicit.
One team, multiple Bounded Contexts
Can a single team manage multiple BCs? Yes, this is usually the norm in small sized organizations.
But well... most small organizations don't seem to care much about boundary separation. In fact, the only way to achieve good separation is to explicitly enforce it: from big visible maps, to segregation of the codebase.
The hardest thing to manage is in fact the cognitive load of the involved developers. You can only be deep into one model at a time. But it will be very easy to blur in concepts that shouldn't be mixed. Just like working in a chocolate shop without ever eating it.
While one team many models can happen, you've got to be very good in making the boundaries explicit.
More teams, one BC
Can we have two teams working on the same model? Apparently, yes. I mean: drawing it seems straightforward.
Unfortunately, two teams on the same bounded context is usually a prelude to a riot. Teams have usually different backlogs and priority, and ambiguity will quickly rot in the codebase accelerating the transition towards a Big Ball of Mud. In general you won't have BCs so big to justify multiple teams working on them. So... No.
Interestingly, the Spotify model goes a little in that direction, relaxing the ownership on the codebase to reduce coordination cost (the communication bandwidth, again), while mitigating the risks of decreasing quality with strong engineering practices. However, they don't have a BIG shared Bounded Context, but many smaller ones with relaxed ownership rules.
One team per BC
The perfect choice seems to be one team per bounded context.
... But some details are left out of the picture. Like organization size, for example. I counted 20 different Bounded Contexts in our internal software the last time that I checked. Does it mean that we need 20*(7±2) developers to write our software? For a company of 5? Come on!
But size isn't the only problem here: the different BCs are not evolving at the same pace, same will be growing. Other will stabilize and ideally be left untouched for a long time, but the notion of an idle team isn't that popular in the enterprise, one risk being filling up a backlog just because the team is available. The association between a team and a Bounded Context is a temporary one, and will change over time.
However, the focus of context mapping isn't in the shape of the teams but in the relationships between models that have to support collaboration.
One interesting concept is the notion of being upstream or downstream: mapping the political influence of one model versus the other one. But based on this type of reasoning, we have a few patterns describing possible collaboration types. Here is a quick summary.
- Partnership: two teams are mutually dependent and collaborating towards a common goal.
- Customer-Supplier: the goal is still common but the dependency is less symmetrical, and priorities may differ. Negotiations are anyway possible.
- Conformist: no negotiations here. One model is adopted with minimal changes on the other side. The downstream party just gets what they're given.
- Anti-Corruption Layer: still on the downstream side, but we are not adopting the external model. In fact, we're writing a thick adapter to keep our model strictly separated from the outside one.
- Open-Host: on the upstream side, our model can be made available to external users, at our conditions. Of course, we'll need to make these conditions explicit with documentation and so on.
- Published Language: a common language on the communication channel could make a larger conversation possible, especially if the conversation language is maintained by a third party.
- Shared Kernel: a small portion of the software could be in common between different model, but this implies superior attention and quality in touching this code, not to mention the dependencies.
- Separate Ways: the best dependency is the one we don't have. Sometimes keeping things separated is the way.
- Big Ball of Mud: when boundaries are not in place and the codebase becomes a scary place to work in.
In DDD, this categorization becomes interesting when drawing a Context Map which is a very interesting artifact in a brownfield scenario. Drawing the map forces me to ask the relevant questions before starting the project. For example, I'd wave a red flag if my team is intended to be conformist on an unreliable platform, on a critical project for the business.
Since the early days, I enjoyed the ability of Context Mapping Patterns to capture the cost of the different approaches on different currencies. A Partnership requires less code but a lot of conversational bandwidth to be possible, while an Anti-Corruption Layer goes exactly in the opposite direction, writing more code since no conversation is possible. Conformist will let you go with little code and conversation, but paying in reduced quality instead. No such thing as a free lunch!
Conversational bandwidth is in fact the key currency here. Collaboration won't happen if there's not enough bandwidth to support it.
Comparing the two approaches
The most obvious difference is that Context Mapping doesn't explicitly talk about teams, but about models instead. On the other hand, Team Topologies suggests to optimize for cognitive load, which maps pretty well to the notion of having one team per bounded context.
Present or future state
Talking about the different collaboration patterns, there's some overlapping: like DDD Open-Host and TT Platform Team, or DDD Partnership and Customer-Supplier with TT Collaboration), but the most interesting difference seems to be another one.
Team Topologies provides a reference towards a desirable to-be state, while DDD context mapping provides more fine-grained patterns for assessing the current state.
A Big Ball of Mud is clearly not a desirable state, but it's part of the dictionary needed to describe your horrible daily reality.
I do use context mapping for future state, but mostly as a software design tool, not so much as an organization design tool. Team Topologies seems to have an edge in being use as a reference model here.
Choices have consequences
One thing that the two approaches have in common is making the consequences explicit. Collaborations are costly and these costs need to be properly accounted. I've been in too many places where the management was inviting teams to communicate more while filling backlogs and adding deadlines making communication virtually impossible.
The Team Topologies lightweight dogmatism of there are only 3 types of interaction is a good way to force management to make choices and own consequences. Just telling people to collaborate and communicate is not a strategy.
At the same time, quickly updating our current state Context Map is still a great way to detect bullshit in the current state of collaborations.
- "We are collaborating with team A: we have meetings every week!" → Customer-Supplier?
- "They just say 'No' to every single thing we ask." → No... Conformist.
Team Topologies talks about fracture planes as a natural way to decompose the system into different stream. But I am too much into Domain-Driven Design to fall in love with this metaphor. Well, I know there are ideal places for cutting the system into loosely coupled bounded contexts and to effectively split responsibilities between teams, I wrote an entire chapter in my book about how to extract this information from a Big Picture EventStorming.
... but I also know that when it comes to breaking the monolith, it's never about cutting slate. It's more like chopping wood where there are branches and nodes. You'll try to follow the line, but you'll realize that something isn't getting separated that easily: there will be something that is shared in the wrong way, but that's also big and dangerous to play with.
And this is where the metaphor sounds a little too easy for me. There are ways to deal with this problem (I talked about it in an old presentation: what lies beneath) but they require a given degree of mastery.
What's left out
A few concepts are part of the game, but seem to be missing from the conversation.
- Organization size: Team Topologies starts being interesting when your development shop is 20+ or 50+, while you'll have Bounded Contexts also when you're coding in solo mode.
- Business pressure & portfolio management: designing the perfect harmony between teams will fail miserably without some health check in terms of backlog pressure. If teams are under pressure, collaboration will not happen in the intended way, but I still see too many organizations unable to plan for multiple dependent teams.
A journey, not a destination
I kept my favorite thought for last: I think the most important outcome of the discussion around Team Topologies nowadays is about what a good desirable state looks like. Most organizations have never seen a healthy organization (harsh but true), so providing a reference model is definitely a good thing.
Please don't fall into the trap of considering such desirable state as stable or to solve the problem of team structure once and forever. Every solution will be ephemeral by design. Collaborations are temporary and will need to be reviewed whenever the context changes. But you'll definitely have better tools to make the right decision.
Learn with Manuel Pais and Alberto Brandolini
Manuel is the trainer of the Team Topologies Training Course.