architecture

System Architecture Without Team Architecture is Pointless - Here’s How to Do it Right

"organizations which design systems ... are constrained to produce designs which are copies of the communication structures of these organizations."

— Melvin Conway

This is a rather ambitious article because I’m pulling together numerous concepts, including Conway’s Law, integrated teams, microservices, and interservice communication. Nonetheless, the title says it all. I believe that a system’s architectural plan is not complete without considering the structure and communication channels of the team(s) charged with building and maintaining the system. Thus, if you receive an architectural plan without these considerations, send him or her back to the drawing board or just get a new architect!

Don’t Let the Tail Wag The Dog

I’m a firm believer in Conway’s Law https://en.wikipedia.org/wiki/Conway%27s_law (stated above), and that it should be at the forefront of an architect’s mind when designing systems. If the team structure does not complement the architectural vision, then you have a case of the tail wagging the dog - the org chart inevitably produces the system architecture, rather than the system architecture producing the org chart.

To build performant, scalable, and reliable systems, you want to ensure that the system architecture and the team architecture complement one another to avoid productivity breakdowns in development and system outages in production.

To achieve this objective, I ask myself the following question:

What team and communication structures will complement the architectural vision?

Applying Conway’s Law to Define Complementary Systems and Teams

To illustrate how to answer this question, let’s walk through a scenario of designing a microservice architecture for a cloud-based system. (If you’re not familiar with the concept of microservices I recommend reading Martin Fowler’s introduction https://www.thoughtworks.com/insights/blog/microservices-nutshell. I’ll try to explain some of the main concepts of microservices, but remember that the important lesson is mirroring system and team architectures, not some much the ins-and-outs of microservices.)

Microservice Definition

Architecturally, I define a microservice as the following:

A microservice is a piece of a larger system that encapsulates its data, business logic, and deployment dependencies. It operates as an interdependent system that runs in its own process and communicates with other services via well-defined external interfaces - leveraging protocols such as HTTP, RPC, and AMQP.

Microservice Example

You have an “accounts” microservice that handles data and business logic concerned with users’ identity on the system, is deployed via docker container(s), and orchestrated by Kubernetes.

Integrated Team Definition

Now, let’s define a team architecture that will be similarly structured and tasked with building microservices. We’ll follow Conway’s Law as literally as possible to reverse engineer a definition of what I call an “integrated team.”

An integrated team is part of a larger organization that encapsulates the design, implementation, quality assurance (QA), deployment, and monitoring of a microservice. It operates as an interdependent team that communicates with other teams via well-defined external interfaces - leveraging channels suchs as chat, forums, in-person meetings, and documentation.

Integrated Team Example

An integrated team is charged with the design, implementation, QA, deployment, and monitoring of our hypothetical accounts microservice (and other related services). The team encapsulates these functions by having all of the requisite skills among its ranks.

system-team-architecture.png

A Complete Example

Let’s go through the process of creating an architectural plan for a system that also lays out the complementary team architecture. In this case, we’ll design a hypothetical mobile application that manages personal finances. Our application will deliver the following features to end users:

Dashboard

  • Authentication and Identity (i.e. Sign Up, Login, etc.)

  • View analytics of personal income and expenses

  • Integrate bank and investment accounts

Goal Manager

  • Set goals and milestones to compare against real outcomes

  • Track achievements and receive rewards

  • Receive reminders and encouragement to keep goals in focus

Ask an Expert

  • Discover qualified personal financial managers

  • Schedule appointments to discuss strategy and milestones

  • Communicate via chat, audio, or video

System Architecture

For the cloud services in our system, we’ve decided to implement a microservice architecture. Each major feature (i.e. Dashboard, Goal Manager, Ask an Expert) will be comprised of approximately 4 microservices that encapsulate all of the necessary business logic and data.

Communication Structure

We anticipate numerous data dependencies between systems. For example, the analytics dashboard will need access to achievements data to display in the analytics panel. To keep the systems’ data encapsulated, we don’t want the dashboard reading directly from the achievements database, or we’ve re-coupled our systems.

Without delving too deep into interservice communication, we can resolve this data dependency in [primarily] two ways. First, we could have Analytics ask Achievements directly by making an HTTP or RPC request (strong consistency). Or secondly, we could use an eventual consistency mechanism - whenever Achievements writes new data to its database, it broadcasts the operation on a message queue so Analytics can update its own database with the new information.

Now, we have an architectural vision that (a) encapsulates the major systems features via microservices, and (b) resolves interservice data/communication dependencies through strong and eventual consistency (direct and async) mechanisms. The figure below depicts the architecture that we’ve put together.

system-team-architecture (2).png

Complementary Team Architecture

Now that we’ve established the architectural vision for our software, we need to develop a complementary team and communication structure to implement and operate our microservices. Following Conway’s law, we want to structure our teams and communication channels to mirror our architectural vision. Therefore, just as we have three major features, we’ll have three major teams - each in charge of a feature and its constituent microservices.

Communication Structure

To handle dependencies between teams, they will need to communicate directly with one another (strong consistency) as well as broadcast messages to keep other teams abreast of potentially relevant information. Therefore, in mirroring our system architecture, we can produce a very similar team and communication architecture.

system-team-architecture (3).png

To see how the team architecture mirrors the system architecture, I’ll put them side by side.

comparison.png

Caveats

In creating our team structure, We’ve made a few assumptions that may not pan out in the real world. First, we may not have the budget or head count to operate three fully-integrated development teams. And second, perhaps one of the features really doesn’t require a dedicated team.

Regardless of the case, I recommend preserving the three-team structure to closely mirror the systems, but allow individuals to belong to multiple teams. This preserves a complementary system-team architecture and a clear chain of responsibility for each feature and microservice collection.

Conclusion

When architecting a system, don’t let the tail wag the dog and allow existing organizational structures produce a system that is a mere copy of itself and its problems (Conway’s Law). In this article we’ve explored a hypothetical personal finance app that leverages Conway’s Law to produce a microservice ecosystem and complementary team structure. Ultimately, this process will produce the best outcomes as measured by scale, performance, and reliability - for both the system AND the dev shop.