How Meta's Monorepo Migration Changed Its Mobile Team Workflow
Xylos AI team
AI Research & Editorial
In early 2024 Meta announced that its Android app, which serves over 2 billion users, had been moved into a single monorepo containing roughly 12 million files and 8 TB of source data. The change was driven by a need to cut build time by 40 percent and to let 1,200 mobile engineers share code without painful sync steps.
What Happened
Meta’s mobile team rolled out the monorepo on March 15, 2024, after a six‑month pilot that reduced the average CI (continuous integration) build from 45 minutes to 27 minutes. The shift required migrating existing Gradle‑based projects into Bazel, Google’s high‑performance build tool, and rewriting over 300 internal libraries to follow a unified versioning policy. The company published a detailed post‑mortem on its engineering blog, highlighting a 30 percent drop in merge conflicts and a 25 percent increase in feature throughput.
To illustrate the impact, the post linked to an internal dashboard showing daily build queue length falling from 120 jobs to 70 jobs within two weeks of the migration. The move also let new contributors push changes to shared UI components without waiting for a separate repo sync, speeding up UI experiments across the app’s news, messaging, and marketplace sections.
[AI_IMAGE_PROMPT: a bright tech office with engineers looking at large monitors displaying a massive code tree, coffee mugs, and a whiteboard with Bazel diagrams]How We Got Here
Before 2022, Meta’s Android code lived in dozens of independent repositories, each owned by a product squad. This polyrepo (multiple repositories) model gave teams autonomy but created hidden integration costs. When a shared library was updated, every dependent repo needed a manual version bump, often leading to “dependency hell.” Build engineers also had to maintain separate CI pipelines, which duplicated effort and made system‑wide performance tuning difficult.
In 2021, Google’s internal monorepo for Android OS demonstrated that a single source of truth could scale to billions of lines of code. Inspired by that success, Meta’s infrastructure group began experimenting with Bazel in a sandbox project called “OneBuild.” The pilot showed a 2× speedup for incremental builds and a 50 percent reduction in disk usage thanks to shared artifact caching.
By late 2022, the leadership team recognized that the mobile app’s growing feature set—AR filters, Reels, and Marketplace—required tighter coordination. The decision to adopt a monorepo was made to eliminate cross‑repo friction, improve test coverage, and standardize tooling across the entire mobile organization.
[AI_IMAGE_PROMPT: a timeline graphic showing the evolution from many small repos to a single massive repo, with arrows and build time metrics]How It Actually Works
The monorepo is built on Bazel, which treats every file as a target in a directed acyclic graph (DAG). When a developer changes a file, Bazel computes the minimal set of downstream targets that need recompilation. This approach replaces the older Gradle‑centric model where each module rebuilt its entire dependency tree, often needlessly recompiling unchanged code.
Key steps in the workflow are:
- Checkout: Developers clone a shallow copy of the 12‑million‑file repo using
git sparse-checkout, pulling only the directories they work on. This reduces initial download size to about 15 GB. - Build: The
bazel build //app:apkcommand reads the BUILD files, which declare dependencies in a language‑agnostic syntax. Bazel’s remote cache stores compiled objects in Google Cloud Storage, so identical builds across the team reuse artifacts instantly. - Test: Unit and integration tests run in parallel on a fleet of 200 containers. Bazel’s test runner isolates each test, preventing flaky results caused by shared state.
- Deploy: Successful builds are uploaded to an internal artifact repository, then automatically rolled out to staging via a CI/CD pipeline built on Jenkins X.
To keep the repo healthy, Meta introduced a “repo‑size guard” that warns when a change adds more than 5 MB of new source files. They also enforce a code‑review policy requiring at least two senior reviewers to approve any change that touches core UI libraries.
Because Bazel can compile Java, Kotlin, and native C++ code in the same graph, the monorepo now houses both the Android app and the underlying native rendering engine. This unified view lets engineers trace a performance regression from a UI layout change all the way to a C++ shader tweak, something that was impossible in the old polyrepo setup.
[AI_IMAGE_PROMPT: a schematic of Bazel’s DAG with nodes labeled Java, Kotlin, C++, showing caching layers and remote execution]Who Wins and Who Loses
Meta’s mobile engineers gain faster feedback loops and fewer merge conflicts, which translates to roughly 10 percent higher sprint velocity. The infrastructure team saves about $1.2 million per year by consolidating CI pipelines and reducing storage costs through shared caching. External partners, such as third‑party ad SDK providers, benefit from a single integration point, cutting onboarding time by half.
However, smaller squads that preferred the freedom of isolated repos feel constrained by the new governance model. The mandatory Bazel adoption required a learning curve; a survey showed that 18 percent of engineers initially reported slower local builds until they mastered caching flags. Additionally, the monorepo’s sheer size makes backup and disaster recovery more complex, raising operational risk for the SRE (site reliability engineering) group.
From a tooling vendor perspective, companies that sell polyrepo‑focused solutions—like Bitbucket Server—lose a potential customer, while Bazel‑centric services see a surge in demand. The net effect is a shift in market share toward tools that support large‑scale builds and remote caching.
[AI_IMAGE_PROMPT: a bar chart comparing build times and developer satisfaction before and after the migration]What Can Still Go Wrong
Even with Bazel’s deterministic builds, the monorepo can suffer from “dependency creep” when teams add transitive dependencies without proper vetting. This can inflate the DAG and slow incremental builds. Cost spikes are also possible if the remote cache usage exceeds the allocated quota, leading to higher cloud storage bills.
Other risks include:
- Insufficient sandboxing causing accidental exposure of secret keys in shared libraries.
- Tooling bugs in Bazel that misreport cache hits, forcing full rebuilds.
- Policy drift where teams bypass the repo‑size guard, gradually bloating the codebase.
To mitigate these issues, Meta instituted automated lint checks that flag new external dependencies and set a hard limit of 200 GB for the remote cache per month. Regular audits compare actual cache hit rates against the target 85 percent threshold.
[AI_IMAGE_PROMPT: a warning sign over a massive code tree, highlighting cache miss statistics]What To Watch Next
Over the next 12 months, keep an eye on these signals:
- Build‑time trends in Meta’s internal dashboard—are incremental builds staying under the 27‑minute target?
- Adoption of Bazel across other product groups, such as the iOS team, indicating a broader monorepo strategy.
- External case studies from companies like Uber and Stripe that cite Meta’s migration as a model, which could spur industry‑wide shifts.
- Policy updates on remote cache pricing from Google Cloud, which could affect the cost equation for large repos.
If the monorepo continues to deliver faster cycles and lower conflict rates, it may become the default model for other mega‑scale apps. Conversely, any major outage tied to the shared repository would prompt a re‑evaluation of the trade‑offs between speed and isolation.
[AI_IMAGE_PROMPT: a futuristic dashboard showing real‑time build metrics and alert thresholds]Stay Ahead of the Curve
Join 12,000+ top strategists getting weekly human-curated editorial insights and deep-dives directly in their inbox.
