Skip to content
Time to Signal

All notes  /  Build

One Repository or Many

The choice affects build speed, tooling cost and coordination. Neither answer is free, and the costs land on different people.

Analysis

The repository layout argument is usually conducted as a matter of taste. It is more usefully treated as a set of trade-offs with predictable consequences.

What a monorepo gives you

Atomic changes across boundaries. A change to a shared library and all its consumers lands in one commit, verified together.

One version of everything. No dependency resolution between internal components, no diamond problems, no "which version of the shared library is this service on".

Shared tooling. One build configuration, one lint setup, one test runner.

Visibility. Finding all usages of something is a search rather than an investigation.

Refactoring becomes possible at a scale that is impractical across repositories.

What it costs

Tooling requirements go up sharply. A large monorepo needs a build system with proper dependency modelling, remote caching, test selection and sparse checkout. Without them it is a monolith that everyone rebuilds constantly.

Checkout and clone times become a problem at scale.

Continuous integration must be selective, or every change runs everything.

Access control is coarser, which matters in some organisations.

Ownership becomes a convention rather than a repository boundary, and conventions need enforcement.

What many repositories give you

Independent release cycles, which suit teams shipping at different rates.

Simpler tooling per repository. A small repository with a simple build needs none of the above.

Clear ownership, enforced by the boundary.

Faster checkouts and simpler CI for any individual repository.

What that costs

Cross-cutting changes become projects. A change to a shared library means a release, then a bump in every consumer, then coordination.

Version skew, where different services run different versions of the same internal library, and the bugs that produces.

Duplicated tooling, which drifts. Twelve repositories acquire twelve slightly different CI configurations.

Reduced visibility. Nobody knows what depends on the library they are changing.

The honest summary

A monorepo moves cost from coordination into tooling.

Many repositories move cost from tooling into coordination.

Which is better depends on which you can afford. A small organisation with two services should not build a monorepo platform. A large one with a hundred interdependent components will spend more on coordination than the platform would have cost.

The failure modes

A monorepo without the tooling is the worst of both: everyone rebuilds everything, CI takes an hour, and nobody can make an atomic change because the pipeline is too slow to verify one.

Many repositories without a dependency story produce version skew nobody can see, and an upgrade that takes a quarter.

Both failures are about tooling investment, not about the layout choice, which is why the argument about layout usually misses the point.

If you are moving

Do the tooling first. Selective CI, caching and dependency modelling must work before consolidation, not after.

Migrate incrementally, with both layouts coexisting for a period.

Measure rebuild breadth and CI duration throughout. If they get worse, stop and fix the tooling before continuing.

Expect it to take longer than planned, and expect the tooling work to be most of it.

The prerequisite checklist

Before consolidating repositories, five capabilities that must already work.

Dependency modelling, so the build knows what depends on what.

Test selection, or every change runs everything.

Remote caching, or every developer rebuilds the world.

Selective CI, triggered by affected paths.

Sparse or partial checkout, at sufficient scale.

Without these a monorepo is a monolith, which is the worst outcome available and the usual one when the layout change precedes the tooling work.

Deciding without migrating

Most organisations asking the question do not need to change layout at all.

Name the pain first. Cross-cutting changes, or version skew, or duplicated tooling, or slow builds.

Check whether the tooling fix addresses it without moving anything. Frequently it does.

A shared CI configuration, a dependency update bot and a common build wrapper solve much of what a monorepo is proposed for.

Migrate only when the coordination cost is measured and exceeds the tooling cost, and say which number you are relying on.