Services

Resources

Company

Conway's Law as a lever to fix legacy architectures

Conway's Law as a lever to fix legacy architectures

Conway's Law as a lever to fix legacy architectures

Conway's Law as a lever to fix legacy architectures

You have probably heard about the Conway's Law. Melvin Conway said it in 1967 and it has stood the test of time. Simply put, here's what it says:

Organizations will design systems that mirror their own communication structure.

But there's a follow-up question that you have probably never thought about.

If org structure shapes the architecture, what to do when you already have a legacy architecture that you want to fix?

In this blog post, we answer this question: “How do you fix legacy architectures with Conway’s Law”.

What Conway's Law looks like in an organisation

Let me take an actual example from one of the organisations we worked with. A while ago, I was in an architecture refactoring meeting where a team had built a “Policy Evaluation Engine”.

The system received messages, ran them through a series of policy checks and decided what to do with them downstream. The core and domain heavy part of the system was the policy evaluation. There were two kinds of policies: “allow policies” and “deny policies”. Each of the allow and deny policies would have 100s of policies, that need to be executed in DAG (Directed Acyclic Graph) manner to ultimately decide how the incoming message was to be further sent to downstream service.

A simplified legacy architecture of Policy Evaluation Engine
A simplified legacy architecture of Policy Evaluation Engine

The Deny policies have to be executed first. If the message doesn’t trigger any of the deny policies, only then it will be evaluated against all the allow policies. The diagram above is an oversimplification, and the domain was pretty complicated with many nuances that I am glossing over.

In that meeting, someone asked: "Who owns this shared policy database"?

A long pause and silence in the room…

There was no clear single owner for the database. Over time, this shared database had grown massively (terabytes of data). And this is where a lot of problems such as slow performance and slower product iteration velocity had started.

Multiple teams were reading and writing to the same shared database. Neither team felt “fully” responsible for it. If one team needed to add a column, they'd have to coordinate with other teams to make sure things don’t break for them.

That database had become the exact kind of coupling Conway predicted. Organizations will design systems that mirror their own communication structure. The teams were communicating via this shared database that their system components couldn't stay independent. This is Conway’s Law in practice.

The corollary of Conway's Law

If communication structure determines system architecture, then the reverse is also available to you: if you want a specific architecture, you can deliberately set up your team communication structure to “produce” it.

This is what people call the Inverse Conway Maneuver, or Reverse Conway Maneuver.

In practice, here’s how it gets implemented.

  1. You have a legacy system that you want to refactor.

  2. You’d brainstorm to come up with the target state architecture for the system.

  3. You’d design the team structure and org chart that will produce the target state architecture.

The idea is to have the target state architecture ready beforehand. And use Conway’s Law and its corollary as a “lever” instead of thinking about it as a “constraint”.

The idea is so simple, when you get it.

Instead of letting the org chart determine your architecture, you devise the org chart that will produce the architecture that you desire, with appropriate team boundaries.

How we used the Reverse Conway Maneuver

Back to the policy evaluation engine. Based on this learning, we ended up carving out two separate teams for evaluating allow and deny policies. We had a target state architecture in mind that allowed each team to fully own its domain.

One team owns the allow policy evaluator end to end: its service, its database, its API surface. Another team owns the deny policy evaluator the same way. They communicate via a contract, in this case it was the Kafka message passed between stages.

Because each team owns their full domain, they can make schema decisions without asking each other. They can optimize their storage for their access patterns. They can deploy independently. The database fragmentation that looked like a problem from the outside was actually the evidence that the “service boundary” is real and a clear separation is needed.

An updated architecture of Policy Evaluation Engine
An updated architecture of Policy Evaluation Engine

If you had one team responsible for both evaluators, they would eventually share a database. Sharing the database is not always the problem, but the shared database leads to high coupling in software systems. With a shared database, you can’t iterate independently (at least, it’s not easy). If the teams shared the database, they’d eventually build shortcuts and hacks like creating a shared utility. Six months later you'd have a big-ball-of-mud policy evaluation engine that's harder to split and scale independently.

Is this really “that” important in practice

The pushback for Conway’s Law I usually hear from experienced engineers goes something like this: "You're saying the team structure is more important than the technical architecture. That doesn’t feel right."

It's a fair instinct. As engineers, we're trained to make technical decisions on technical grounds. But what this misses is that technical decisions don't live in a vacuum. They get made by humans who are under organizational pressure and time pressure to deliver quality software on time.

A very crude but relevant analogy that I can make is about home renovation. You need different skill sets (plumber, electrician, carpenter, architect etc) when renovating your house. Their boundary of collaboration needs to be defined and needs to be clear. Otherwise, this “org” structure will create an “architecture” where you’d have electrical wires running alongside the water pipes potentially resulting in electrocution when things fail.

Reverse Conway Maneuver allows you to refactor large legacy systems that involve people and technology components.

What to watch out for

A few things that tend go wrong based on my learning so far:

The platform team gap.

When you split services by domain, you often realize there's shared infrastructure that nobody wants to own, like, provisioning databases, managing secrets, standardizing logging. If you don't explicitly create a platform team (or equivalent) responsible for this, every domain team will reinvent their version of “platform” slightly differently. Conway's Law applies to platform work too. A good read for this is “Team Topologies” book.

Shared infrastructure isn't the same as shared ownership.

In the policy evaluation engine example, both the deny policy team and the allow policy team were downloading from the same object storage bucket. That's fine. Object storage is shared infrastructure, not shared ownership. A database with a schema (and domain knowledge) that two services write to, is different. That’s shared ownership, which is the coupling you're trying to avoid.

Conway's Law doesn't care about your intentions.

If your team boundaries don't match your architecture, the architecture will drift toward the team boundaries over time, regardless of what you intended. This is Conway’s Law in practice. If you want a certain architecture, the team structure has to be designed accordingly.

How can you apply this in your work?

Most successful applications of Reverse Conway Maneuver I have seen involve these things:

  • Acknowledging the effects of Conway’s Law and clear buy-in from top to address the tech-debt.

  • The target state system architecture that’s already defined

  • An external team with less context of legacy systems

I was recently discussing this with a colleague and here’s what I told them.

You either die before Product Market Fit or live long enough to see the effects of Conway’s Law in your system architecture.

At early stages with smaller teams, the effects of Conway’s Law aren’t that visible. But when the team and system complexity grows (thanks “software entropy”, but that’s probably a separate blog post on its own), the effects cannot be avoided.

First step to fixing any problem is acknowledging the problem exists. Teams that understand and acknowledge the effects of Conway’s Law are better prepared to deal with its consequences. Fixing legacy architectures require a clear buy-in from the top leadership. Period. This cannot be done in isolation by individual teams. Typically, a CTO or CIO has to be involved in this decision making.

The second step is to actually define what the target state architecture should look like. Brainstorm about this architecture, figure out its failure modes and see that it doesn’t succumb to same decision from the existing architecture.

This is where (typically), an external team comes in. This team must have less context of the legacy system to not be bound by its existing constraints. If the team knows too much about existing systems, this knowledge will influence their decisions. Worst case, they’d end up with a very similar architecture, defeating the whole purpose of refactoring.

At One2N, we have had decades of experience in refactoring legacy systems without slowing down the business growth and without having to rewrite the massive systems from scratch. We don’t suggest big-bang rewrite that takes years with no ROI in sight from leadership point of view. Instead, we refactor systems and components using clever but proven techniques that show results in weeks instead of quarters. If this is something you want to talk about, reach out to us.

In this post
In this post
Section
Share
Share
In this post

section

Share
Keywords

Conway’s Law, Reverse Conway Maneuver, Inverse Conway Maneuver, legacy architecture refactoring, team structure and system design, shared database coupling, microservices boundaries, platform team responsibilities, backend engineering best practices, refactoring legacy systems without rewrite, team topologies software architecture, org structure and architecture alignment

Continue reading.

Subscribe for more such content

Get the latest in software engineering best practices straight to your inbox. Subscribe now!

Hold to verify for 2 seconds

Security powered by system

Subscribe for more such content

Get the latest in software engineering best practices straight to your inbox. Subscribe now!

Hold to verify for 2 seconds

Security powered by system

Subscribe for more such content

Get the latest in software engineering best practices straight to your inbox. Subscribe now!

Hold to verify for 2 seconds

Security powered by system