Hi, Pablo here

back to home


Conway's Law cuts both ways

Published: 2026-09-28

This article is a small reflection on a useful way to look at Conway's Law that I think many people working in software have not observed. I'll assume you're familiar with Conway's Law. If not, here are some nice explainers so you can get on the same page:

So, to the point: most of the time I bump into someone bringing up Conway's Law, they do so to highlight how the organizational and communication structure is impacting the systems that get built. "We should split this team into two so one takes service A, the other takes service B and they can work independently". Or, "it's pointless that we all try to build on a monolith if the three teams we have are in different time zones, have different managers and barely talk with each other". I also find it's used more retrospectively than proactively. That is: more as an explanation of how a system came to be the way it is (and usually used when it's fucky), rather than a tool to try to influence how a system ends up being. Thoughtworks did introduce the Inverse Conway Maneuver, which at least tries to leverage the law as a tool of change instead of an a posteriori explainer. Plus: I've never met anyone in real life who was familiar with the inverse maneuver.

Where I would like to bring some attention is to the idea of putting it the other way around, in the direction of the law: looking at how the code/system changes the org/comms. And to try to use this as a way to influence the outcomes of the org, not as a postmortem explanation.

Let me discuss some examples.

Enforcing boundary contracts

In large enough engineering orgs, you end up having Alice's service depend on Bob's public interface. When these contracts are purely internal, Bob ends up introducing unexpected breaking changes more often than Alice would like, for a variety of reasons. With the consequences being only internal and attributable to reasonable human error, I've noticed that serial contract breakers like Bob only get called out if their breakages lead to serious outages in a very immediate and direct way.

In one specific instance, I witnessed this setup, which I found interesting: Alice herself added some automated CI checks in Bob's repo that enforced what she needed out of his public interface, set up in a way that wouldn't allow Bob to go to production while breaking that. Furthermore, she leveraged CODEOWNERS to set the repo up so that only her review was valid for these CI checks.

Bob would have to align with Alice on every breaking change. This resulted in some behaviour changes:

The monolith that wanted to couple

In another instance, I worked in a small team that revolved around a single repo. The repo itself held a monolith, which was an intentional architectural decision by the group's technical leader. But another intentional decision by him was that different modules of that monolith had to stay decoupled from each other: he wanted to push harder for a modular monolith, hoping to avoid the dangers of microservices while reaping the advantages of a single monolith and of decoupling at the same time.

There were several tricks in his toolbelt to ensure this wasn't broken. One of them was to literally prevent imports across modules. Each module could only talk to others through shared infra or explicitly defined public APIs. CI checkers would enforce this hard, flagging PRs that tried to skip it.

A few consequences of this:

The keys to the secrets

Another org was struggling with a sprawl of SaaS and infra services being hired left and right. The org had grown from a small team to multiple independent teams, and each team was just going around shopping for whatever cloud tooling was useful for their work. It quickly grew into a mess of duplicated services, where common needs such as observability, documentation or even databases were being served by two or three tools where one would have been enough.

The org was lucky enough that at least Git and their pipelines were still centralized in a single place, so the following single change was made: one single engineering team, led by a very assertive manager, was put in charge of the secrets manager that was used by their CI/CD pipelines. You could only go to production through it, and only this manager could actually edit the contents of the vaults to include whatever tokens/keys/secrets your tooling needed.

Once this was decided, the first impact was quick: the sprawl stopped because, if you wanted another tool, you had to convince that manager, which was anything but trivial. The second effect came in slowly, as certain tools were promoted over others and deprecation dates were set under the threat of secrets disappearing from the vaults. Initially, this setup was overwhelming for the team sitting on top of the secrets manager, since they suddenly became a bottleneck for pretty much every other team in the org. But the pressure incentivized everyone to adapt: the gatekeeping team quickly standardized all their business-as-usual to make it as fast and scalable as possible. The teams depending on it quickly learned to plan ahead when secrets management was part of some line of work, and developed the habit of using what they had available in the org instead of just picking any shiny SaaS that was walking by.

The take away

That's just a few. I could add more, and you would suddenly get bored because the pattern becomes obvious. The overarching story to take away: you make some hard rule in code. Because code is stubborn, people adapt around it and so your organization and how people work change as a result.

As someone who has both technical and managerial responsibilities, I find this mindset of changing the org via the code interesting and useful. I will often find myself thinking: which technical decision will drive the behaviour that I want to see in my org?

Is the solution to flip-flopping, mind-changing product owners to make messages containing the words "urgent", "change" and "priority" undeliverable in Slack?


back to home