Multi-repo vs Mono-repo, why not both?

Couple years ago, it was very popular to debate multi-repo vs mono-repo approach to structuring codebase.

Primarily this was a side-affect of microservices popularity and people starting to question where do we place the code for all the services. Some large companies are using enormous mono-repo, for which they had to develop whole special filesystem/git support just to clone it. With all that investment in mono-repo it must be worth it?

Mono-repo

Idea for mono-repo is simple and i see it as a natural progression in a team which doesn't think about this issue too much. You already have code for one service, why not add future code right next to it, that way you can share the common code and more importantly, it's easy to start writing the code.

But, thinking more about it, we can think of at least couple of downsides: tight coupling between services is easy to do, and without special care it's something that will happen; deployment pipeline can become the same for all services in the repo, which means that all services are deployed/released at the same time which can introduce so called "distributed monolith"; what happens when the team maintaining the services grows too large and becomes two or more teams, how do we ensure code ownership and separation of concerns between teams.

Multi-repo

This approach is commonly seen as more complex one. And it is. It introduces more things to manage, more repositories, permissions for those repositories, any automations tied to it (CI/CD), context shifts when developers have to switch between repositories and codebases, harder to share common code...

But, it of course brings benefits, otherwise we wouldn't discuss about it. The common benefits are that it forces more separation between codebases which means separation between services. Hopefully this causes other good side-effects like services being deployed independently, developers not stumbling upon each other's toes when working as many smaller repositories mean less merge conflicts.

Why not both?

At my previous company, when we started designing the architecture, services, team structures, we knew that we will have at least three services with very different resource requirements, team owners and release schedules. So it made sense to split those using multi-repo approach.

But one of those services was big, a monolith. And that was totally fine. As we were small team having one monolith service made it easier to refactor, implement, release changes.

If the team would grow, some parts of the monolith would need to scale independently or would need some special hardware (GPUs) etc. We could then split that chunk to a new service.

Split them as you need to, not just because you can.

Not all teams are equal

The benefits and issues listed before are not the universal truths. And it entirely depends on a team, company, culture if those happen or not. As having multi repo doesn't necessarily mean independent deployment of services, some teams use multi-repo and still put a lot of effort to do just the opposite, to somehow have multiple repos (services) that are batched together in a single deploy.

So, choosing any of those won't do you any good, without making sure you are actually oriented towards those goals as a culture.