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