Cross-team dependencies should be low-contextCross-functional teams or highly specialized teams? Both can work, but the latter requires low-context dependencies.
Yesterday I was struck by a bit of a seeming paradox.
Parts of the agile community love to tout the benefits of “cross-functoinal teams.” A cross-functional team is one that has all the skills necessary to build, manage, and release a value-providing feature, from end to end. Typically that means at least backend and frontend skills. Sometimes it might also mean a UI/UX designer, or QA, or a DBA, or some other specialty, depending on the needs of the team.
However, the largest, most successful tech companies don’t always do this. Let’s consider Amazon.
They took quite the opposite approach, and built an entire suite of teams (and later, public-facing services) called “Amazon Web Services”, which are dozens of specialized, hyper-focused services that are managed by hyper-focused teams.
If you’re working on the Amazon web site, and you need to store an image somewhere, you just use the S3 service, provided by the S3 team. You don’t have an “image storage engineer” on your team doing it for you.
I’ve long thought that highly specialized, service-focused teams makes sense within agile, and the book Team Topologies helped re-enforce this belief.
But I’ve still been left with a bit of cognitive dissonance about this issue… until yesterday, that is. Yesterday is when I heard Mary Poppendieck say something that made it click for me. She was speaking with her husband Tom on the No-Nonsense Agile podcast, when she explained how shipping containers were a breakthrough in the industry of shipping. If you want to send a load of, say, chairs, across the world, you could do it the old way: Label each chair with a delivery address, and drive them down to the shipyard, then load them onto the ship one at a time, stacking them carefully, then telling the ship crew to be careful about this one special chair, because it’s fragile… whatever.
With the adevent of shipping containers, you instead load all your chairs into a container. Then you send that container down to the shipyard, which is loaded onto a ship, along with hundreds or thousands of seemingly identical containers.
My first thought hearing this was “This seems to contradict the idea of one-piece flow… now we’re batching things.” And I guess that might be true. But sometimes batches are appropriate.
But the epiphany came when I realized that the important piece of this analogy was the context that has to be communicated between the two parties (the chair manufacturer and the shipping company).
When you ship hundreds of individual chairs, you must communicate a lot of context. Minimally, one address per chair; even if they all go to the same retailer upon arrival, as well as some sort of size/shape information, for the purpose of storing and stacking the chairs such that they won’t fall during transit.
In contrast, when you ship a container of chairs, this is very low-context. You have the same number of chairs, but now only one address. And it’s a standardized size and shape, so no special size/shape requirements.
Of course, the individual addresses may still exist, and the chair-stacking Tetris game may still happen. But these things now happen within the confines of the shipping container, such that the shipper doesn’t need to know or care about any of it.
When an Amazon dev team stores an image in S3, a similar transaction takes place. They make arrangements with the S3 team to use some of their resources. From then on, the S3 team doesn’t care about the images, their names, sizes, or even if they’re images at all. The arrangement between the dev team and the S3 team is very low context.
One more example: This concept allows the Internet to work (or physical highways, or countless other things. What’s your favorite example?) The IP protocol, especially when coupled with TCP and UDP, allows us to send arbitrary data between two endpoints, in such a way that everyone in the middle has a low-context understanding of what’s going on. In fact, usually all we want the middle parties to know is the source and destination address (and sometimes not even that). IP is a very low-context protocol.
Not all dependencies are created equal
What makes the Linux kernel as a dependency less problematic than another team in your company as a dependency?