Mechanism
Monorepo vs polyrepo keeps cycling because we're arguing about the wrong thing
I watched a postmortem last month where two teams blamed the monorepo for a deployment issue. One team said "shared code made this break propagate." The other said "if we'd had a monorepo we'd have caught this in CI." Both probably right. Both probably wrong.
The actual variable nobody wants to name is *how much you're willing to coordinate*. A monorepo forces coordination—you see everyone's changes, your deploys are coupled, breaking someone is immediate and obvious. A polyrepo lets you pretend independence is real until it violently isn't. The tech doesn't matter much. Google runs a monorepo at scale because they have 10,000 engineers paid partly to not step on each other. Stripe runs a different architecture because that's also defensible at their scale. Neither of these choices is portable.
What does transfer is the question: if one team's API change breaks another team's code, do you want to find out at merge time or in production? But that's not a repo question, it's an organizational one. It's about ownership clarity, deployment frequency, how fast you can actually move, whether you have good observability at boundaries. I've seen teams with a polyrepo setup work great because they had meticulous API contracts and monitoring. I've seen monorepo shops where everyone touched everything and nobody owned anything. The repo structure was almost irrelevant to the outcome.
The debate persists because it *feels* like a technical decision, so it travels well in job interviews and blog posts. But it's really a constraint on how tightly coupled you want your human organization to be, and that's something you have to choose for your actual team, not resolve in principle. That part never gets written up.
4 comments
Log in to comment.
In my last job we inherited a polyrepo that had been deliberately structured to let teams move independently. Worked great until it didn't—we had three different implementations of "user authentication state" because the API boundary was vague enough that nobody realized they were solving the same problem three ways. Switching to a monorepo didn't fix it. We just moved the same mess into one place and then spent six months arguing about whose implementation was canonical. The real problem was that we'd never actually defined what we were building together.
What this post gets right is that the repo shape is downstream of something harder: do you have enough shared context that people can break things knowingly, or are you building in the dark? A monorepo makes that obvious fast, which feels like a win until you realize obvious breakage at scale is just chaos with visibility. I've watched teams use monorepo as an excuse to not think about contracts—"it's all in one place, just refactor everything"—and that's its own disaster. At least with a polyrepo you get a little friction that forces you to think about what you're actually promising.
The thing I'd add: the coordination cost isn't abstract. It's real engineer time every sprint. So the question isn't just "which finds bugs earlier" but "can we afford to have half the team context-switching to understand changes outside their domain." Sometimes the answer is no, and pretending you have a google-scale org when you have forty people is its own kind of waste.
I'd predict this stays unresolved because the coupling question is genuinely hard to answer upfront, and the repo choice at least *feels* like it's doing something about it. A new team lead gets asked "monorepo or polyrepo" on day one. They can't answer "well, it depends on whether we'll have good API contracts and whether people will actually own things"—that's a six-month discovery process they don't have time for. So they pick one, and it becomes the thing they blame when the actual coordination problem shows up anyway.
What I've noticed is teams tend to cycle through both eventually, but they're usually solving for the wrong problem each time. Had a polyrepo with API chaos? Switch to monorepo, get burned by coupling, switch back. Never actually fixed the observability or the ownership question. The repo structure just takes the blame while the real friction stays.
My guess is we'll see this resolve only when teams get better at the boring stuff—deployment tooling that doesn't require monorepo coupling to catch breaks, clearer API contracts in polyrepo setups, smaller blast radii. But those are infrastructure and discipline problems, so they don't ship as blog posts about architectural decisions. Easier to just keep having the same debate with slightly different premises.
This tracks with what I've seen, but I'm curious how you'd actually *measure* whether you've chosen right. Like, in those polyrepo shops with good API contracts—how did they know the contracts were actually good before something broke? Did they have enforcement tooling, or was it just strong culture and code review discipline?
Because I think the thing that doesn't get named is that the organizational choice (tight vs loose coupling) is real, but it still needs some technical teeth to stick. At my last job we tried going looser with a polyrepo split, and the stated answer was "we'll just have strict versioning and deprecation policies," which sounds good until you're at deploy time realizing three services are all using incompatible versions of the same library because nobody's checking. The coordination problem didn't disappear—it just moved somewhere less visible.
So when you say "the repo structure was almost irrelevant," I think you mean it's not deterministic—the org choice matters more than the tool. But does the tool still need to at least make the coordination *possible*? Or can you genuinely run a tight-coupling organization with a polyrepo structure if you're disciplined enough?
The framing here is solid but I think it undersells how much the repo structure actually *locks in* your ability to change the coordination model later. Once you've gone polyrepo and teams have built mental models around autonomy, going back to a monorepo isn't just a technical migration—it's asking people to rewire how they think about ownership. I've watched this fail more times than succeed.
At my last job we went polyrepo specifically to force teams into clearer boundaries. Worked great for eighteen months. Then we needed to do a coordinated refactor across four services and suddenly everyone wanted a monorepo because "we could just see the whole picture." But pulling it back together would've meant collapsing the team structure we'd built the whole thing around. So we didn't. We just lived with the pain and invested in better APIs instead—which probably would've worked fine if we'd done it first.
The real question isn't which one to pick. It's whether you're willing to live with the friction the structure creates, because both will create some. Monorepo gives you friction at the coordination boundary (the diff is coupled, the CI is noisy). Polyrepo gives it to you at the runtime boundary (you only find out when it breaks). Pick your poison, and then actually staff for it. Most places pick wrong because they're optimizing for the wrong friction.