Coinbase had nearly a thousand services in separate repos, where a fix to a shared library could take months to roll out. So they bet on a Bazel monorepo.
A one-line library fix that took months to ship is what a monorepo is supposed to kill.
By mid-2020 Coinbase ran nearly a thousand services across separate repositories, and shared libraries — logging, server boilerplate, authn/authz — were depended on by many or all of them. In that polyrepo world, every internal library had to be versioned and published, and every consuming team had to bump their version to pick up a change.
The other half of the pain was deployment. Coinbase’s proprietary tool Codeflow was built on the assumption that one GitHub repository equals one Docker image equals one deployment per AWS account. Features had been bolted on to allow more, but the result was a stiff, opaque chain from source code to release that got harder to learn with every addition.
REQUIREMENTS
What they actually needed from a code layout
Stated plainly, Coinbase wanted three things. Code sharing without a publish-and-version dance. A single source of truth so that a change to a widely-depended library immediately triggers the test suites of every dependent service. And an explicit, transparent way to define the relationship between source code and what actually gets deployed to their cloud — the thing Codeflow had made opaque.
Underneath all of it was a strategic requirement: to stop investing in internal, proprietary tooling and position the company on industry-standard tooling instead.
THE OPTIONS
Keep bolting onto Codeflow, or change the assumption
The path of least resistance was to keep extending the existing developer-productivity tooling — more Codeflow features to smooth over the polyrepo edges. But every new feature led to an even steeper learning curve, because each one added another proprietary relationship engineers had to understand. Coinbase describes choosing instead to put a pause on that tooling and head down the “contentious path of monorepo.”
THE CALL
Bazel, with a dependency graph and a shared cache
Coinbase chose a Bazel monorepo. In a monorepo there is, by definition, only ever a single version of a given library; any change to it is immediately rolled out to the whole company and its impact is measured by the monorepo’s test suite. Bazel supplies the piece that makes this survivable — an explicit build dependency graph, so a commit builds and tests exactly what it affects rather than the entire repository.
Because that graph still bottoms out in libraries almost everything depends on, even building one project could take an hour. So the real engineering was caching: making builds hermetic — deterministic outputs regardless of which machine or time of day runs them — so outputs can be aggressively cached and reused across CI and developer machines. That meant SHA-pinning or vendoring every dependency and keeping the host system out of the build.
CONSEQUENCES
What you sign up for when one repo holds everything
By the time of writing, the monorepo held over 100 projects and 22% of Coinbase’s daily deployments across Go, Ruby, Node, and Python, with a stated goal of migrating the whole company by early 2021. But collapsing every project into one repository broke Coinbase’s security model, which assumed one GitHub repo equals one project and was enforced at the repo level — leaving a “one size fits all” problem where the whole monorepo would be policed at the level of its most sensitive project. Their answer was to adapt their internal review-gatekeeper, Heimdall, to read a generated CODEOWNERS file rolled up from per-directory OWNERS files, so each directory could require its own reviewers.
The unfinished edges were named honestly. Developers still built on their laptops and couldn’t use the shared caches, so the plan was to give each engineer a remote Linux machine in EC2. Bazel had no strong support yet for React and React Native. And the tooling that scaled to ~100 projects was expected to face growth of over an order of magnitude, straining their caching, version control, and build strategies.
A monorepo doesn’t remove the hard problems of scale — it trades a thousand small versioning problems for one enormous caching, security, and tooling problem, and it only pays off if you actually solve that one.
A plain-language, AI-drafted and human-edited retelling of the article published on blog.coinbase.com, reorganized and explained in our own structure and words, with original analysis in the editor's note above. The facts, numbers, and decisions belong to the original author and are not altered. For the full depth, read the source.