airbnb4 min read

Curated summary

Migrating Airbnb’s JVM Monorepo to Bazel

Read original(opens in new tab)

Airbnb migrated its tens-of-millions-of-lines JVM monorepo from Gradle to Bazel over 4.5 years, achieving faster builds, testing, IntelliJ syncs, and development deployments. The move was driven by Bazel’s scalable remote execution, hermetic builds, and ability to provide shared infrastructure across Airbnb’s language-specific repositories. A gradual rollout, extensive automation, and close collaboration with service teams were central to making the migration successful.

Results of the Migration

  • Build CSAT increased from 38% to 68%.
  • Local build and test times became 3–5 times faster.
  • IntelliJ syncs became 2–3 times faster.
  • Development-environment deployments became 2–3 times faster.

Why Airbnb Chose Bazel

Faster Builds Through Remote Execution

  • Large Gradle builds frequently took more than 20 minutes locally, while pre-merge CI builds had a p90 of 35 minutes.
  • Gradle had already been optimized with powerful machines and build sharding, but sharding caused underutilization and duplicated shared work.
  • Bazel’s cacheable actions and remote build execution enabled thousands of actions to run in parallel on short-lived workers.
  • “Build without the Bytes” reduced the amount of build output developers needed to download.
  • Bazel analysis runs in parallel, unlike the often single-threaded configuration phase of large Gradle projects.
  • Remote execution also improved local build performance, not just CI performance.

More Reliable and Reproducible Builds

  • Gradle tasks could access the entire filesystem, creating accidental dependencies and race conditions.
  • Bazel sandboxes expose only declared inputs to each action, preventing undeclared files from affecting builds.
  • Bazel’s remote execution runs actions in identical containers with strict resource limits.
  • Using remote execution for both local and CI builds reduced differences between developer and CI environments.

A Shared Build Infrastructure Layer

Because Airbnb’s web, iOS, Python, Go, and JVM repositories all use Bazel, the company could standardize infrastructure for:

  • Remote caching
  • Remote build execution
  • Affected-target calculation
  • Build Event Protocol instrumentation and logging

Starting with a Proof of Concept

  • Airbnb first migrated Viaduct, a large GraphQL monolith platform.
  • Viaduct was selected because it was complex, had slow builds, affected roughly 300 product engineers monthly, and had an infrastructure team willing to collaborate.
  • Bazel and Gradle initially coexisted, allowing developers to choose either system.
  • The team ported Viaduct’s build logic and created an automated Bazel build-file generator because the Gradle dependency graph continued to change.
  • Although Bazel was initially 2–4 times faster locally, developers did not adopt it immediately.
  • The team spent several additional months fixing missing integrations and bugs before Viaduct engineers voluntarily switched.

Scaling Across the JVM Monorepo

  • Airbnb expanded breadth-first, aiming to make the entire repository compile and test under Bazel.
  • Gradle and Bazel continued to coexist during the migration.
  • This allowed developers to use Bazel locally while deployments still relied on Gradle.
  • Gradle provided a fallback when Bazel infrastructure, such as remote caching or execution, experienced incidents.
  • Maintaining two build graphs was costly, so Airbnb invested heavily in automation rather than requiring developers to maintain Bazel files manually.

Automated Build-File Generation

  • The generator was inspired by Gazelle but was built internally to meet stricter performance requirements and handle dependency cycles.
  • It parses Java, Kotlin, and Scala source files to identify packages, imports, and symbol declarations.
  • These relationships are used to construct a file-level dependency graph.
  • Since generation ran on every commit before merging, Airbnb added external caching to keep it fast.
  • CI publishes a cached repository index for each mainline commit, allowing the generator to rescan only directories changed since that commit.

Airbnb’s experience suggests that a large build-system migration is most effective when introduced incrementally: prove the benefits on a representative service, automate maintenance, preserve a fallback during rollout, and address developer workflow issues before expanding across the organization.

Continue with another curated summary.