DEV Community

Marcel Czuryszkiewicz
Marcel Czuryszkiewicz

Posted on

Your Software Architecture Is Quietly Copying Your Team

If this is too long, tldr: Google Conway’s Law wath yt video and think

There is a popular rule in software development called Conway's Law. It says that organizations design systems that mirror the way people inside those organizations communicate. In simpler terms: Your architecture will eventually look like your team structure. Big company with separate frontend, backend, data, DevOps, and platform teams?

You will probably end up with separate services, separate processes, separate ownership, and a lot of API calls between people who sit in different Slack channels. But what happens when the entire company is just two people? That is where things get interesting.

At bundle.social, we are running a unified social media API that handles a lot of edge cases. And there are two of us. There is no dedicated platform team No analytics department No infrastructure group. No product manager translating customer feedback into Jira tickets. Just two people are trying to keep a fairly large system moving without turning it into a pile of slop services nobody fully understands. You would think Conway's Law does not really apply to such a small team. It absolutely does. It just shows up differently.

How Conway’s Law Works in a 2-Person Team

When you have 50 developers split across departments, Conway's Law creates microservices and cross-team dependency hell. When you have two developers, Conway's Law forces your system into one of two extremes: The "Two Halves of a Brain"

Split: Service A belongs entirely to Person A, and Service B belongs entirely to Person B.

Because human communication between two people has practically zero friction, it's extremely tempting to drift into the lazy version of Conway's Law: ignoring technical boundaries altogether because "we can just talk about it on Slack." Why write explicit API documentation when you sit next to the person who wrote the endpoint? Why enforce strict domain boundaries when you can just export a helper function across modules in 5 seconds?

That's the trap G.

When communication is effortless, your architecture turns into a mirror of two individual mental models mashed together. And if one person goes on vacation or takes a weekend off, the remaining half of the team is left staring at a black box they never touched.

The Trap of the "Hero Service"

We handle social media integrations dealing with changing platform schemas, rate limits, OAuth refreshes, and webhooks across multiple networks.

In the early days, if Person A (me) built the LinkedIn integration, it lived entirely in Person A's head. If Person B built the video processing pipeline, it was Person B's private territory.

Conway's Law meant our architecture wasn't mirroring an organizational chart it was mirroring our individual brain dump.

We realized very quickly that when on-call duty represents 50% of the entire company, you cannot afford "Hero Services." If a background job fails at 2 AM (it did), the architecture needs to be understandable by whoever happens to be holding the phone, without requiring a 30-minute explanation.

How We Design Architecture for Two People

Instead of fighting Conway's Law, we decided to leverage it intentionally. Here is how we design our system to fit our real-world team dynamic:

The "Pragmatic Monolith"

Over Microservices We don't need 10 microservices communicating over gRPC. That setup mirrors an enterprise with 10 separate team leads. Instead, we maintain a clean, modular monolith. Code is co-located, deployments are simple, and mental overhead is kept to a absolute minimum.

Code Boundaries Over Personal Preferences

Even though we can reach into any part of the codebase, we enforce strict domain boundaries and clear interfaces. We treat internal modules with the same care we'd treat an external API. If a new feature requires a massive, messy cross-domain hack, it's a sign that our architectural boundaries are getting as sloppy as our task lists. Our Rule of Thumb: If it takes more than 2 minutes to explain how a module handles errors to the other person, the module is over-engineered.

Asynchronous Code, Asynchronous Context

We write code assuming the other person will have to debug it with zero warning. That means:

  • Standardized error handling across all integrations
  • Self-healing background workers over manual intervention scripts
  • Clear log traces over "tribal knowledge."

Design for the Team You Have Today

The biggest mistake small startups make is building architecture for the 500-person company they hope to become in five years.

They end up paying an immense "architectural tax" managing Kubernetes clusters, distributed tracing, and complex microservice orchestration with a team of two.

Your architecture will always reflect your team structure. Don't fight it, and don't pretend to be Netflix.

Embrace the 2-person dynamic: keep it lean, keep it unified, and build a system simple enough that either of you can steer the ship alone without sinking it.

Takeaway is this

Your system will reflect how you divide problems, how you discuss them, and where information gets stuck. Don't mess that up.

Ps I actually wrote that for Medium but got zero traction, so maybe you will find it helpful

Top comments (1)

Collapse
 
algorhymer profile image
algorhymer

I'm 90% on your side.

Remaining 10% doubt is a little bit... weird, but maybe you might find it constructive.

Your statement is

Your Software Architecture Is Quietly Copying Your Team

I'd add:

Team is Copying S&P-500 Lazy Corpo Thinking

So, transitively the statmenent could be:

Your Software Architecture Is Quietly Copying S&P-500 Lazy Corpo Thinking

Most companies you join do the exact same mistakes, have the exact same problems, have the exact same management staff.
At the end, we get a sort of sloppy, lazy, unimaginative, 0-care version of Huxley's Brave New World.

The most important thing is not that it destroys quality.
The most important thing imo is that it gets boring after you've seen it unfold 6-7 times.
There isn't that much thinking and brain power behind most software nowadays.
Also... companies tend to use tech from 2014, 2011... 1990.
The problem isn't that it is old.
The problem is that management most of the time is unaware of their own tech stack.
They think about new tech, and they fail to admit that:
New tech is dessert.
To eat new tech, you have to eat first the broccoli, aka: stabilize the 1000 years old subsystem, lock it into place via tests, and be aware that it exists, and be insanely open about it.
Sweeping it under the rug, not talking about it in meetings, fantasizing about grand migrations is what causes raging fires on the servers for example.
Owning the past requires admitting fault and weakness.
Corporate people by nature are incapable of that.
In a culture of vanity, virtue signalling and desperate status reaffirmations, the only option is to not talk about problems, which will then become worse and worse over time.

Startups are of course are terrible too. I mean almost criminally bad, but since anyone can write code, the bar is so low that the justice system does not really treat software engineering as a legitimate sue-able field of engineering.

After seeing how startup codebases are swallowed after a corpo buyout: Startups simply write horrible cowboy code. All were like that. When that horrible cowboy code meets the big corp's blast from the past level 90s style code... that's when the swallowing will stop.
Instead of a unified system, you'll have the main body of boomer code, and there'll be the adhd code from startup slopists.
Aka the S&P500 whale, instead of swallowing the startup slop, will have a startup cyst in it.

This is my experience, your mileage might vary.