Communication patterns, team dynamics and organizational structure all lead to specific architectural decisions. The code itself can reflect the values, attitudes and assumptions of the team that created it — and we can use this knowledge to our advantage to build more effective and sustainable systems that reflect the needs and goals of the organization. But how?
The Art of Writing Code
Recently, I’ve gotten quite keen on observing people. Not in a weird way; I mean figuring out their behavioral patterns, social interaction and team dynamics. Studying the way they communicate, and the way they write code. I know what you’re thinking: The way they write code? Coding is anything but social. What does it have to do with their behavior or social interaction?
Surprisingly enough, a lot.
Writing a piece of software is a process of assembling systems of components that interact with one another. It involves a wide range of skills — and, contrary to popular belief, understanding the syntax and grammar of a programming language is just the fundamental layer. Writing code is more than that; it’s almost like an art.
Just like artists paint on a canvas, we engineers use code as our brush to create a functional, beautiful piece of software. And just like artists, we are influenced by our environment and surroundings. Artists express their feelings and emotions, while we express our understanding of the system’s functionality. The way the code reads says something about us and our environment.
“The architecture of the system gets cemented in the forms of the teams that develop it.”
— Ruth Malan, “Conway’s Law”
Conway’s Law was outlined in 1968. We’ve come a long way since then – containers, microservices, public clouds and event-driven systems, to name a few. Nevertheless, despite being discovered over 50 years ago, Conway’s Law still applies. It’s critical in understanding how you, as an individual contributor, perform in an organization given its organizational structure.
Translated into layman’s terms, Conway’s Law means that a product’s architecture tends to mirror the structure of the organization in which it is developed, i.e., the organization produces designs that are copies of its communication structure. Now isn’t that interesting? Let me give you an example.
Adidas: Conway’s Law in Action
In 2018, Adidas underwent an engineering transformation on a large scale, as the then-VP of Platform Engineering, Markus Rautert, describes in his talk at the DevOps Enterprise Summit. Up until that point, the organization was structured for horizontal delivery — meaning there were horizontal teams focused on application development, testing, integration and operations and support. These teams were bridged by a team of specialists, such as PMs, business analysts and software architects.
At the time, Adidas had roughly 60,000 employees. The horizontal teams suffered from cognitive overload and, as a result, they struggled with productivity and delivery. The organization needed a cultural change. That cultural and structural change is described by Markus as the Reverse Conway Maneuver (more on that later).
Adidas knew what product it wanted to build, but its operational model didn’t match that product. They decided to do a wide-scope structural change and move towards a fluid organization with clearly defined domains, scope, interaction models and communication patterns. The critical change was that instead of structuring the organization by roles of engineers, they structured the teams by their product domain — hence becoming a product-oriented team organization.
Through cross-functional teams aligned with business needs (and other specialized platforms), Adidas managed to increase the release frequency of their digital products by 60 times!
The Power of a Team-first Model
Adidas isn’t the only company that’s gone through major organizational changes. Among others, Spotify is also well-known for its “Spotify model” of organization. This people-driven, team-first model where people are organized in a product-oriented way has proven very efficient as it promotes autonomy, leads to engagement and reduces the cognitive load on the engineers.
Why is that, though? Why is it that when the architecture of the system and the architecture of the organization do not match, the organization’s architecture wins?
Perhaps it’s because certain software architectures cannot be effectively pursued by an organization — since the necessary communication paths simply do not exist or are difficult to follow. The engineers then opt for a simpler way, willingly or subconsciously. This means that if we want our organization to explore or adopt certain design patterns, we should reshape the organization to remove obstructions and support this initiative.
In particular, an organization that is arranged in functional silos (where teams specialize in a particular function, such as QA or Data Science teams) is unlikely to ever produce software systems that are well-architected for end-to-end flow.
Similarly, an organization that is arranged primarily around sales channels for different geographic regions is unlikely to produce effective software architecture that provides multiple different software services to all global regions. Think about this for a moment. It is often the case that we expect the same behavior from all the departments in the company. But should this be the case? If the organization structure is set such that the QA department is functionally isolated and does not integrate with the other teams, then it is likely that, when tasked to create an end-to-end automated flow, the architecture will reflect this functional isolation.
“Team assignments are the first draft of the architecture.”
— Michael Nygard
The approach that can be used to support engineering as much as possible in delivering the desired results is called the Reverse Conway Maneuver. I know — sounds like some masterful military strategy of moving a warship 180° in a split second. Luckily, it’s not that complicated. The maneuver (sometimes also called the Inverse Conway Maneuver) states that to achieve the desired architecture, the organization should evolve its team and organizational structure to support such architecture.
To clarify the importance of the organizational structure that fits the requirements and design patterns, and to demonstrate the application of this maneuver, let’s apply it to a specific case.
Imagine you have the following team structure.
- 4x Fullstack Engineer
- 1x Database Administrator
- 1x Operations Engineer
You split the fullstack engineers into two stream-aligned teams: Team A and Team B (Figure 1). You would think that creating the two teams separated by a business domain would guarantee the loose coupling that you want to achieve with your architecture, wouldn’t you? Let’s see what’s likely to happen.
According to Conway’s Law, the architecture that emerges from such a team structure would match the structure — in that there would be a single repository holding frontend (FE) and backend (BE) components, a single shared database (DB) and a single infrastructure repository holding the infrastructure’s code (IaaC). The fullstack engineers would optimize for a monolithic structure, the single database administrator (DBA) would drive the emergence of a single shared database, and the same would happen with the operations engineer (Figure 2).
You may argue that it depends on the seniority of the engineers. And you may be right. However, human beings tend to trade off optimality for simplicity in the long run. Meaning we converge to whatever feels easiest for us. How can we avoid this, then?
The answer is an ultimate uno reverse move: the Reverse Conway’s Maneuver. The idea behind this is that instead of thinking of teams first and architecture second, we think of architecture first. The team structure should match the architecture it is meant to produce.
If our idea is to break the tight coupling, we would probably want separate FE and BE components, and have a database per BE component. On the other hand, having a single IaaC might be desirable as it allows for the deployment of an application as a whole — which should make it easier to guarantee the compatibility of individual components.
The changes to the team structure are described in Figure 3. You may notice that we now need 1 more DBA engineer. It might be tempting to resolve this simply by allocating 50% of the DBA to Team A and 50% to Team B, but note that this would lead to the exact same problem as described above.
What we can do, however, is take a different DBA (from an unrelated product) and reduce the allocation of both DBAs to 50%. It’s key to pick a product that has a low cohesion — a.k.a. their internal elements are unrelated — with this product. According to Conway’s Law, this team structure naturally produces the intended architecture.
As you can see in Figure 4, the resulting architecture perfectly matches the team structure.
If we accept that there is a relationship between the organization’s structure and the architecture it produces, we also have to accept the implications of this — meaning that anyone making decisions about the team structure or the shape of the organization needs both social and technical skills, as they strongly influence the software system. They need to understand people and work within the social framework as well as within the technical framework.
These days, companies often promote a culture of transparency, communication and collaboration. Drawing boundaries between teams puts boundaries between software components.
On the other hand, promoting communication and collaboration between organization units increases the cohesion of the software components they create. When handled carelessly, the culture itself can introduce unwanted interaction patterns that result in tightly coupled teams. Based on Conway’s Law, we know that this interaction pattern will result in tightly coupled components the teams produce. To prevent this, the organization should facilitate team interactions for trust, awareness and learning, but clearly define team boundaries and communication practices. The company should define team APIs.
The term API stands for Application Programming Interface. It’s commonly used in software engineering as a specification of interaction between software components. However, we can extend the idea to interactions within the company and design team APIs. The team API defines a contract for communication and helps ensure that all involved parties understand how they should interact with each other. Much like the programmatic API, it helps to set expectations of their behavior, responses and requests they are able to process.
The design should be driven by the concepts such as availability, scalability and ownership. The team owns the resources that belong to its “scope” — which is a domain that promotes the separation of concerns between teams and managers to decrease the cognitive load. All resources within this scope are wholly owned by the team but meant to be consumed by other teams, effectively promoting cross-team collaboration. The team should be scalable, new team members should be able to be integrated within the team at ease and the API should promote cross-team pairing.
Much like programmatic APIs, we can assume that any team may become a potential DOS (Denial of Service) attacker; they can overwhelm other teams with requests. These interaction patterns should be identified. Real-world software services would approach this in various ways — for example, by introducing quotas, throttling to individual components or simply scaling the component that becomes a bottleneck. Analogically, we can scale the team, add quotas to other teams or throttle “requests” by proper prioritization and queueing.
I am not suggesting treating engineers like they’re software components. I am simply pointing out the similarity between the organization and team structure and the software architecture.
Whether consciously or subconsciously, people notice these interaction patterns and become intrinsically affected by them, as is suggested by Conway’s Law. Such a relationship can be used to our benefit by promoting an organizational structure that supports the architecture we want the teams to produce. We can build efficient teams, reduce the cognitive load on engineers and improve the delivery in terms of both speed and quality.
Various other concepts contribute to the output of the team — such as office layout and team interaction modes — but these are beyond the topic at hand. Still, I highly encourage you to explore them. When looking at “code as culture,” there’s no shortage of areas to probe.