At FilmTailor we'd got to the point where every new service meant a new repo, a new pipeline, and a new set of "wait, which version of the shared library is this one on?" conversations. Nothing was broken exactly. It was just death by a thousand context switches: five terminals open, five READMEs slightly out of date, and PRs that touched three repos because one API contract changed.
The fix was obvious enough on a whiteboard: pull everything into a single monorepo. The bit that wasn't obvious was how, if you actually care about keeping your git history intact rather than just copy-pasting source files in and losing a decade of blame annotations in the process.
Beyond fixing the "which repo has the latest version of this?" problem, a couple of other benefits made the decision easy:
Sharing code without an internal NuGet feed. Shared models, DTOs, and common classes could just be referenced directly instead of living behind a private package feed. That sounds like a nice-to-have until you've actually run one: every change means a PR to the shared library, a version bump, a PR to consume the new version in each service, and inevitably a service or two lagging a few versions behind because nobody got round to bumping it. A monorepo makes shared code an internal project reference instead of a package dependency, and the sync problem disappears.






