TL;DR: Monorepo allows atomic source changes across services and can enforce a shared dependency version, at the cost of needing a build system that understands the dependency graph. Many repos give you clean ownership and independent release cadence, at the cost of dependency drift that surfaces as a security patch you have to apply forty times. Pick on which pain your organisation can actually manage.
How to approach it
Refuse to answer in the abstract. Ask how the services relate, whether they share libraries, and whether they deploy together. Then use one concrete scenario to make the trade visible, since that is what the question is asking for.
A strong answer
The scenario that decides it: a shared library has a critical vulnerability and needs patching everywhere.
In a monorepo that is one pull request. Update the library, and CI builds and tests every consumer against the new version immediately, so you find out in one run whether anything breaks. One source merge can update every consumer, but each deployed service still needs to release the patched artifact. Track runtime versions to prove the vulnerable library is gone.
Across forty repositories it is forty pull requests, forty CI runs, forty reviews, and forty deploys, in whatever order teams get to them. Some are on the old major version and need real work. Weeks later you still cannot answer "is the patch everywhere" without tooling that inventories versions across repositories. This is the single strongest operational argument for a monorepo, though organisations also operate large polyrepo fleets with automated updates and inventory.
The counter-argument is equally concrete. A monorepo can enforce one version per dependency, but repository layout does not require it. Under that policy, upgrading means fixing every affected consumer before merging; independently versioned packages can instead coexist. Many repos let a team upgrade when they are ready, which is genuine autonomy rather than laziness.
The cost of a monorepo is the build system. Naively, every change runs every test, so CI time grows with the repository until nobody trusts it. You need a build tool that understands the dependency graph and runs only what the change affects: Bazel, Nx, Pants, Turborepo. That is real infrastructure with a real learning curve, and a monorepo without it becomes unusable at around the scale where it starts paying off. If you cannot commit to that investment, do not choose a monorepo.
The cost of many repos is coordination. A change spanning three services is three pull requests that must merge in order, and there is no atomic commit. Ownership is clearer and cross-cutting change is harder.
Some things are often assumed and are not true. Monorepo does not mean one deployable: services still build and deploy independently, the repository boundary is not the deployment boundary. And many repos do not give you isolation from breaking changes; they give you delayed exposure to them, which is sometimes worse because the breakage arrives later and in unrelated work.
My position: for services owned by one organisation that share libraries and change together, a monorepo with a proper build system, because the dependency argument dominates over time. For services with genuinely separate ownership, different release cadences, or an open-source component, separate repositories. And avoid the migration if the current one is working, because the switch is expensive and rarely the actual bottleneck.
What interviewers probe next
"How do you handle CI time in a monorepo?" Affected-target detection from the build graph, remote build caching, and merge queues to validate combined changes before merging; this catches only failures covered by the required checks. Path-based filters are the naive version and they get it wrong as soon as a dependency is indirect.
"How do you version a shared library across many repos?" Semantic versioning with automated update pull requests (Renovate or Dependabot). It reduces the drift; it does not remove it.
"What about access control?" Directory ownership routes reviews; it does not restrict reading source. GitHub CODEOWNERS is not a path-level confidentiality boundary. Use repository separation when different readers must have access to different source, and enforce review rules independently.
Common mistakes
Choosing based on taste rather than on a concrete operational scenario.
Recommending a monorepo without naming the build system requirement, which is the thing that makes it work or fail.
Confusing repository layout with dependency policy. Separate versions can be intentional, but unsupported or vulnerable versions still need an owner and an upgrade deadline.