Neither Git nor Mercurial is automatically “better” for a huge monorepo. At hundreds of thousands or millions of files, the result depends on the complete system: filesystem monitoring, history transfer, checkout design, server architecture, caches, branching policy, and the workflow around code review. Git offers unmatched ecosystem compatibility and can scale well when those pieces are deployed deliberately. Mercurial’s modular design let Meta add extensions that changed the scaling profile of its Facebook repository. The practical decision is therefore between architectures, not two default command-line clients.
What makes a monorepo “large”?
Repository size is not one number. A source tree with 500,000 text files can stress a client differently from a tree with 100,000 files and years of binary history. Before comparing tools, measure the dimensions that affect real operations:
As an Amazon Associate I earn from qualifying purchases.
- Working-tree file count: status, ignore checks, directory traversals, and checkout bookkeeping become more expensive as the number of paths rises.
- History size: commit count, tree metadata, and rename or merge history determine clone, pull, log, and rebase costs.
- Binary content: frequently revised binaries enlarge storage and make ordinary delta and transfer strategies less effective.
- Branch and head count: every active line of development adds merge, review, and server bookkeeping; an uncontrolled number of heads can become a limit in either system.
- Concurrent users and automation: CI fleets, code-review services, and build workers multiply server requests.
- Server bandwidth and latency: a client that is fast on a workstation can still produce an unacceptable experience if clone, update, or fetch traffic overwhelms the central service.
These dimensions interact. A repository can have a modest file count but an enormous history, or millions of files that most developers never need in a particular workspace. A meaningful comparison uses production-shaped workloads rather than a headline file count.
PC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11Outdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchWhat happened at Facebook, and why it matters
Meta’s Facebook repository provides the clearest published Git-versus-Mercurial comparison, but it is a historical, deployment-specific result rather than a universal benchmark. In a 2014 Meta Engineering description, Facebook reported thousands of commits per week across hundreds of thousands of files. The article contrasted that repository with the Linux kernel’s 2013 scale of 17 million lines of code and 44,000 files, noting that Facebook’s source repository was many times larger by file count.
#1 Best Overall
Meta also explained why a single repository was useful: large changes could be made throughout the codebase while continuous modernization remained manageable. The engineering team evaluated extending Git, then concluded that Git’s internals would be difficult to work with for an ambitious scaling project. The decision was about extensibility and the team’s ability to operate the resulting system, not a claim that Mercurial is always faster or that Git cannot support a monorepo.
The measured improvements in Meta’s deployment
Meta integrated Watchman, a filesystem-monitoring service, with Mercurial so that status did not need to discover every unchanged path by scanning the entire tree. Meta reported that Mercurial status became more than five times faster than Git status for its repository. It also built remotefilelog, which allowed clients to obtain commit metadata while downloading file contents on demand. In the same deployment, Meta reported:
| Operation | Reported result | Qualification |
|---|---|---|
| Status | More than 5× faster with Watchman-integrated Mercurial | Meta’s Facebook repository and environment, reported in 2014 |
| Clone and pull | 10× faster with remotefilelog | Meta’s deployment result, not a general comparison of current releases |
| Large rebases | 2× faster with remotefilelog | Meta’s deployment result on its large-repository workload |
| Mercurial server network load | More than 10× lower | Reported for Meta’s remotefilelog-based architecture |
The important lesson is architectural. Watchman changed the cost of discovering local changes; remotefilelog changed which file history had to be transferred. A default Git checkout and a customized Mercurial stack were not the only variables, so these figures should not be used to predict performance on your repository.
Free tools Windows power users keep installed
One-click scans. No signup required.
How Git behaves in a very large monorepo
Git’s main advantages are broad hosting support, mature CI and code-review integrations, familiar tooling, a large hiring pool, and interoperability with existing repositories. Git is often fast for local operations, particularly when the working set and history fit comfortably on a developer’s machine. Those advantages reduce migration risk and make it easier to connect a monorepo to external teams and services.
Default behavior can become expensive when a status operation, checkout, or clone assumes that every path and every relevant object is local. Large-monorepo programs therefore tend to combine Git with several features rather than relying on the default full-history, full-tree model.
Sparse checkout and sparse working trees
Sparse checkout lets a developer materialize only selected directories or patterns in the working tree. This reduces the number of files that editors, build tools, and local scans see. It does not by itself remove all repository history or object metadata, and changing the sparse definition can trigger checkout work. Sparse trees work best when teams can describe stable ownership or project boundaries; a codebase with constant cross-directory edits may require frequent expansion of the working set.
Rank #2
- Used Book in Good Condition
Partial clone and on-demand objects
Partial clone allows a client to omit some objects initially and fetch them when a command needs them. This can make bootstrap and storage requirements more manageable, particularly when the repository contains long histories or large blobs. It introduces a dependency on reliable access to the object server: commands that touch omitted data may block or fail when the client is offline or the server is unavailable. CI workers must also be configured so that on-demand fetches do not create an unexpected request storm.
The Tool Desk
Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Filesystem monitors
Git can use a filesystem monitor to learn which paths changed instead of repeatedly examining every file. The benefit is greatest when the tree is huge and most files are unchanged between commands. Monitor correctness and lifecycle management matter: missed events, a restarted monitor, or a network-mounted workspace can force a more expensive scan or produce confusing status results. Measure cold-start and recovery behavior, not only the fastest warm-cache run.
Object caches, alternates, and virtual workspaces
Shared object caches and local alternates can prevent every clone or CI job from downloading identical history. They require explicit storage management and isolation rules so that one job cannot corrupt or unexpectedly retain another job’s objects. A virtual filesystem can go further by presenting a large logical tree while materializing files on demand. This makes the developer’s active working set, rather than the repository’s total size, the dominant cost, but it adds a service and another failure mode.
How Mercurial addresses different scaling pressures
Mercurial’s command model is often described as simpler, and its implementation was designed around extension points. Its own documentation treats large-repository performance as several separate problems rather than one “maximum repository size.” It cites successful use of repositories with more than 100,000 files and 200,000 changesets while warning that larger histories, binaries, hundreds of thousands of files, server-side bundle generation, and branch-heavy histories need different mitigations.
Shallow clones for long histories
A shallow clone transfers only a bounded portion of history. This reduces initial transfer and local storage, but historical commands and operations that cross the shallow boundary need a policy for obtaining older changesets. It is appropriate for disposable CI workers or developers who need current code, less so for workflows that routinely inspect or rewrite deep history.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Largefiles for binary-heavy trees
Mercurial’s largefiles extension keeps large binary content out of the normal changeset exchange path and retrieves it separately. That can prevent every clone from carrying every binary revision. The trade-off is operational: binary availability, retention, backup, and offline behavior become an additional service concern. Teams should decide which binaries are mandatory for a build and whether a developer can work without the rest.
Rank #3
Fsmonitor for expensive status scans
The fsmonitor extension addresses the same basic pressure as a Git filesystem monitor: discovering local changes in a tree with hundreds of thousands of files. It is most valuable when file events are reliable and the monitor can recover safely after sleep, reboot, or workspace relocation.
Clone bundles for server efficiency
Generating a complete clone bundle on demand can consume substantial server CPU and disk bandwidth. Clonebundles let a server advertise pre-generated bundles so clients can obtain bulk data from an appropriate location before requesting incremental changes. Bundle production, invalidation, distribution, and access control still need to be operated; the feature shifts work rather than eliminating it.
Generaldelta for branch-heavy histories
Generaldelta changes how revisions are delta-compressed so storage does not depend as heavily on a single linear path. Mercurial documents it as a response to branchy histories that can otherwise waste space. It does not replace a branching policy: a repository with a very large number of active heads still incurs merge, review, and metadata costs.
History transfer and checkout: the decisive performance differences
For a large monorepo, “clone speed” is not a single metric. Separate the work into the following stages:
| Stage | Questions to measure | Typical levers |
|---|---|---|
| Bootstrap | How long until a developer can edit and build a small project? How much data is transferred? | Shallow or partial history, clone bundles, object caches, remotefilelog-style on-demand content |
| Working-tree materialization | How long to create or change the visible tree? | Sparse checkout, virtual filesystem, filesystem monitor, workspace-local caches |
| Update or pull | How much metadata and file content arrive for an ordinary change? | On-demand file history, server-side caching, incremental bundles |
| History-heavy work | What happens during a large rebase, merge, blame, or cross-project refactor? | Local object availability, delta strategy, head count, server round trips |
On-demand designs improve the common case when a developer touches only a small portion of the tree. They can make an offline or degraded-service incident more disruptive because omitted history or file content is unavailable locally. A full local clone has higher setup cost but preserves more offline capability. The right choice depends on whether your organization values minimal workstation footprint or uninterrupted local operation.
Modern stacks blur the Git-versus-Mercurial boundary
Meta’s later tooling illustrates why the client name is an incomplete description of a monorepo system. Meta describes Sapling as a Git-compatible client derived in part from Mercurial concepts, paired with Mononoke as a scalable server and EdenFS as a virtual filesystem. Meta states that this compatible stack is intended to serve tens of millions of files, tens of millions of commits, and tens of millions of branches, and that it is used primarily for the company’s large monolithic repository.
Rank #4
The design goal is to make operations scale with the files a developer is using rather than with the total repository size. Specialized metadata services, caches, and virtualized workspaces can preserve familiar version-control semantics while moving repository-scale work away from a single local checkout. Other organizations may assemble a different combination, but the pattern is widely applicable: evaluate the client, server, storage, workspace layer, and CI behavior together.
Quick wins for a faster PC:
Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Repair Windows errors before they cause bigger problemsFix Now →Branching policy can outweigh the client choice
A monorepo’s head topology is a first-class scaling axis. Trunk-based development, short-lived branches, stacked changes, merge queues, and review-based landing each impose different costs. A team that creates a head for every experiment may overload merge and review systems even if file operations are fast. Conversely, an aggressive single-trunk policy can require dependable presubmit testing and fast rollback procedures.
Meta has described large-monorepo branching as a trade-off between scalability and developer experience. Benefits include unified dependency management and large-scale refactoring, but they require workflow rules that keep integration predictable. Mozilla documentation warns that both Mercurial and Git have known scaling problems as the number of repository heads approaches infinity. Head cleanup, branch lifetime limits, and explicit ownership of long-running release lines should therefore be part of the architecture review.
Questions to ask about heads and merges
- How many active heads exist during a normal week, and how many appear during a release?
- Are changes landed directly to a trunk, through a merge queue, or by merging long-lived branches?
- Does code review represent one commit, a stack of commits, or a merge result?
- Can developers rebase or update while offline, or does the workflow require a central service?
- What automated action removes abandoned heads and stale review branches?
Which should you choose?
Choose Git when ecosystem compatibility is the dominant constraint
Git is the pragmatic choice when your organization depends on existing hosting, CI, IDE, review, deployment, and automation integrations; hires primarily from the Git ecosystem; or must interoperate with many external repositories. Plan to deploy the scaling features that your measurements justify: sparse or virtual workspaces, partial history, filesystem monitoring, object caching, and server-side support for high concurrency. Treat those services as part of the product, with ownership, monitoring, upgrades, and incident procedures.
Choose Mercurial when modularity and existing expertise fit better
Mercurial is attractive when the team values its command model and extension architecture, already operates Mercurial infrastructure, or needs to tailor history and workspace behavior deeply. Meta’s experience demonstrates that extensions such as Watchman integration and remotefilelog can materially change performance. You still need to operate the associated monitors, metadata services, storage, and caches, and you must verify integration with the tools your developers and CI use.
Choose a compatible specialized stack for extreme scale
At tens of millions of files or commits, a conventional full local checkout may be the wrong abstraction regardless of client. A Git-compatible client with a scalable server and virtual filesystem, as illustrated by Sapling, Mononoke, and EdenFS, can preserve familiar workflows while limiting local work to the active slice of the repository. This path has the largest systems footprint and should be justified by measurements showing that simpler sparse or partial approaches are insufficient.
Best Value
How to run a fair evaluation
Do not benchmark empty repositories or synthetic trees alone. Build a representative copy with the same file-type mix, history shape, binary revisions, generated files, branch topology, and review workflow that production will have. Compare complete stacks, including server configuration and workspace layer.
- Define target workloads. Include initial bootstrap, warm and cold status, checkout or update, diff, commit, log and blame, pull or fetch, branch creation, rebase or stack update, merge, and a large cross-project refactor.
- Use realistic environments. Test developer laptops, CI workers, remote or network-mounted workspaces if they are supported, and the slowest network regions your team serves.
- Record both warm and cold behavior. Repeat tests after caches are populated, then clear filesystem, object, and server caches. Report the distribution, not just the fastest run.
- Measure resource costs. Capture client CPU, memory, disk use, server CPU, storage I/O, network bytes, request counts, and concurrency under a realistic number of users and jobs.
- Test failure and offline modes. Disconnect the central service, stop the filesystem monitor, expire a cache, and interrupt a partial transfer. Document which commands continue locally and how recovery works.
- Vary head count. Repeat merge, rebase, update, and review-queue tests with the number of active heads expected during ordinary development and releases.
- Set acceptance thresholds. Define maximum bootstrap time, interactive status latency, update time, CI queue impact, workstation storage, and server bandwidth before choosing a tool.
Common mistakes and their remedies
Comparing default clients instead of deployed systems
A full Git clone against an on-demand Mercurial deployment answers a narrow historical question, not the one your team faces. Enable equivalent monitoring, sparse or virtual workspaces, history depth, caching, and server capacity before drawing conclusions.
Optimizing only the first clone
A fast bootstrap does not guarantee responsive status, checkout, merge, or refactor operations. Track the entire developer day and the CI lifecycle, including repeated updates and large changes.
Ignoring offline behavior
Partial history, remote file content, and virtual filesystems reduce local storage but increase dependence on central services. Decide which tasks must work during an outage or on an airplane, and prefetch or materialize the necessary data for those tasks.
Letting branch heads grow without a policy
No filesystem monitor can compensate for merge queues and metadata overwhelmed by an uncontrolled head count. Establish branch lifetime, landing, and cleanup rules alongside repository tooling.
Underestimating operational ownership
Monorepo extensions are production infrastructure. Assign owners for bundle generation, object or metadata storage, filesystem monitors, virtual workspace services, cache invalidation, backups, and migration procedures. Include their failure modes in on-call practice.
Bottom line
For a huge monorepo, choose the stack that meets your measured workloads and operational constraints. Git usually wins on ecosystem reach and staffing flexibility, provided you add the workspace, history, monitoring, caching, and server architecture needed at scale. Mercurial can be an excellent foundation when its modularity and your team’s expertise enable extensions such as filesystem monitoring and on-demand file history; Meta’s 2014 results show how substantial those changes can be in one environment. At the extreme end, a specialized client-server-virtual-filesystem system may matter more than whether the command name is Git or Mercurial. Benchmark the complete architecture, control the number of heads, and make offline and failure behavior explicit before committing.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

