Bazel / Buck2 / Pants

Bazel, Buck2, and Pants are hermetic build systems originally developed by Google, Meta, and Toolchain respectively to handle the scale and correctness requirements of massive monorepos.

L3 · SYSTEMATICWhat this level takes
MUSTNot met, not at this level
  • Incremental builds run only changed targets (not full rebuild)
  • Remote execution (EngFlow or equivalent) distributes build steps across multiple machines
  • The main codebase uses a build tool with a dependency graph and a shared cache (Bazel, Buck2, or Pants)
SHOULDExpected in practice, not required
  • BUILD file maintenance is assigned to specific team members or automated
  • Remote cache hit rate exceeds 80%
EVIDENCEHow you would check
  • Bazel/Buck2/Pants BUILD files in repository
  • Remote execution configuration (EngFlow, BuildBuddy, or equivalent)
  • Build log showing incremental target selection
DEPENDS ON
  • Infrastructure L2 (Build System) - basic caching and parallelization must be in place before advanced build system adoption

What It Is

Bazel, Buck2, and Pants are hermetic build systems originally developed by Google, Meta, and Toolchain respectively to handle the scale and correctness requirements of massive monorepos. Unlike Maven or Gradle, they require developers to explicitly declare every dependency in BUILD files - every source file, every library, every generated artifact has a declared rule. This explicitness is what enables their core properties: hermeticity (builds don't depend on the host environment), correctness (a build with the same inputs always produces the same outputs), and fine-grained incrementality (only the targets that actually depend on a changed file are rebuilt).

Hermetic builds are the foundation of reliable incremental compilation. When the build system knows the complete, precise dependency graph of every file in the repository, it can determine exactly which targets need to be rebuilt when a source file changes. If you change a utility function in a leaf library with 3 dependents, only those 3 targets rebuild - not the entire codebase. This is categorically different from Maven's module-level incremental compilation, which still recompiles entire modules when any file within them changes.

Buck2 is Meta's reimplementation of Buck in Rust, released as open source in 2023. It addresses several limitations of the original Buck and competes directly with Bazel for teams starting fresh. Pants is a newer entrant focused on Python monorepos and data science workflows. Bazel has the largest ecosystem, the most integrations, and the longest track record. The choice between them depends on language ecosystem, existing tooling, and team familiarity - but all three deliver the same core value: hermetic, incremental, distributable builds.

The migration cost from Maven/Gradle to Bazel is substantial. Writing BUILD files for a large existing codebase takes weeks to months. The tooling ecosystem is smaller. Developer education is required. Organizations at L3 accept this cost because the payoff at scale is significant: near-instant incremental builds regardless of codebase size, the ability to distribute builds across a cluster, and a build system that can support hundreds of parallel agents each making independent changes.

Why It Matters

  • True fine-grained incrementality - change one file, rebuild only the targets that directly or transitively depend on it, regardless of module structure; this is the property that makes builds fast for agent iteration
  • Hermetic builds eliminate "works on my machine" - agents running on different machines, CI runners with different configurations, and developer laptops all produce identical outputs for identical inputs
  • Remote execution is native - Bazel's remote execution protocol (REAPI) is a standard interface that connects to EngFlow, BuildBuddy, and other distributed build backends; you can't effectively use remote execution without a build system that supports it
  • Monorepo at any scale - Google runs Bazel on a repository with billions of lines of code; the incremental build properties don't degrade as the codebase grows, which is critical for organizations building a large codebase with many parallel agents
  • Dependency correctness is enforced - BUILD files require explicit dependency declarations; circular dependencies, implicit dependencies, and undeclared inputs that silently corrupt caches in Maven/Gradle become build errors in Bazel

Getting Started

  1. Pilot on one service or module - Don't migrate the entire codebase first. Choose a self-contained service with clear dependencies and write Bazel BUILD files for it. Build it with Bazel alongside Maven/Gradle for 4-6 weeks. Measure build time, cache hit rate, and developer experience before committing to a full migration.
  2. Use Gazelle for automatic BUILD file generation - For Go and Java, Gazelle can generate BUILD files automatically from existing source code. This dramatically reduces the manual work of writing BUILD files. For other languages, BUILD file generators exist as third-party tools. Use them - hand-writing BUILD files for a large codebase is not viable.
  3. Configure a remote cache immediately - Bazel without a remote cache only delivers local benefits. Configure BuildBuddy, EngFlow, or a self-hosted cache (GCS bucket or S3 bucket as a Bazel cache backend) from day one of the pilot. Without a remote cache, builds on CI are cold starts that miss all the local cache work.
  4. Establish BUILD file ownership conventions - Every BUILD file should have a clear owner. Use CODEOWNERS to assign BUILD file ownership to the teams that own the code. Changes to BUILD files should go through the same review process as code changes - incorrect BUILD files can cause incorrect builds that are difficult to debug.
  5. Invest in developer tooling - Bazel has steeper developer ergonomics than Maven/Gradle. Install the Bazel IntelliJ or VS Code plugin, configure query tools for dependency visualization (bazel query 'deps(//my/target)'), and set up ibazel for watch-mode builds. The raw Bazel CLI is powerful but unfriendly; tooling makes it acceptable.
  6. Plan for the migration as a multi-quarter project - A full migration from Maven/Gradle to Bazel for a large codebase is a 6-18 month project, not a sprint task. Budget for it as infrastructure investment with a clear ROI: the build time savings for AI agent workflows at scale should be calculable from your current agent iteration volume.
TIP

Run bazel build //... --keep_going and look at the action graph to understand how many targets Bazel would build for a given change. Then modify a single file and run bazel query 'rdeps(//..., //path/to:changed_file)' to see exactly which targets will be rebuilt. This makes the incremental build benefit concrete and quantifiable.

Common Pitfalls

Underestimating the migration effort. Teams that try to migrate to Bazel over a weekend or a sprint discover that writing correct BUILD files for a large codebase with implicit dependencies requires understanding every dependency relationship in the codebase. Budget for 2-4 engineers working on BUILD file migration for 6+ months for a large codebase.

Not configuring a remote cache before measuring build times. Bazel without a remote cache is often slower than Maven for cold builds because Bazel's hermetic sandboxing adds overhead. The performance advantage only materializes with a warm remote cache. Don't evaluate Bazel's performance without a properly configured remote cache.

Fighting Bazel's hermeticity requirements. Bazel requires that all build inputs are declared. Code that reads files from arbitrary locations, shells out to tools not listed in the BUILD file, or depends on environment variables will fail hermetic builds. The temptation is to disable sandboxing to make these builds work. Resist this - fixing the hermeticity violations is the right answer, even though it's more work.

Ignoring Bazel's query tools. bazel query is one of Bazel's most powerful features - it lets you understand the dependency graph programmatically. Teams that don't learn query end up making BUILD file changes without understanding what those changes affect, leading to overbroad rebuilds that negate the incremental build benefit.

Treating Buck2 and Bazel as interchangeable. Buck2 has a different configuration language (Starlark is similar but not identical), different toolchain configuration, and different ecosystem maturity. If your team has Bazel experience, migrating to Buck2 is a significant relearning investment. Choose one and commit.

How Different Roles See It

BobHEAD OF ENGINEERING

Bob's teams have been running agents at scale for six months and build time has emerged as a consistent bottleneck. L2 optimizations (caching, parallel steps, dedicated runners) have helped but hit a ceiling: warm builds are 90 seconds, cold CI builds are 8 minutes. His engineering leads are suggesting a migration to Bazel. Bob is skeptical of the migration cost.

What Bob should do: Bob should commission an ROI analysis before approving the migration. The input data needed: current agent iteration volume (builds per day across all agents), current average build time, projected build time with Bazel and remote execution (typically 80-90% reduction for incremental builds). The output: time saved per day, converted to engineering hours. A team of 20 developers each running 3 agents making 30 builds per day at 90 seconds per build is spending 45 engineer-hours per day on build wait time. If Bazel cuts that to 15 seconds per incremental build, the savings are 37.5 engineer-hours per day. At that scale, the migration investment pays back in weeks, not quarters.

SarahPRODUCTIVITY LEAD

Sarah has been tracking developer-reported friction points and "waiting for builds" consistently appears in the top 3. Developers running agents have learned to batch their agent reviews in 90-second intervals synchronized with build completion. This "build-paced workflow" is a sign that the build system is dictating the agent interaction rhythm - exactly what shouldn't happen.

What Sarah should do: Sarah should quantify the "build-paced workflow" pattern: how much calendar time is agent interaction waiting on build feedback versus doing productive work? She should also survey developers who have used Bazel at previous companies - do they exist on the team? Their experience is valuable signal about migration complexity. Sarah should build a three-scenario comparison: stay at L2 (90-second builds), migrate to Bazel with remote cache (15-second incremental builds), adopt a module restructuring approach (see the compilation bottleneck guide). Each scenario has a cost and a productivity impact. Bazel migration is almost always the right call for teams at scale.

VictorSTAFF ENGINEER - AI CHAMPION

Victor has been running Bazel in his personal projects and has built a prototype Bazel BUILD configuration for his team's main service. The prototype demonstrates 8-second incremental builds versus the current 90-second Gradle builds for a one-line change. He wants to make the case for a team-wide migration.

What Victor should do: Victor should run a 2-week A/B experiment: have 3 developers use the Bazel prototype for their agent workflows, while the rest of the team continues with Gradle. Measure agent iteration cycle time for both groups. The data from this experiment - concrete before/after numbers from your own codebase, not benchmark numbers from Bazel marketing - is what will make the migration case compelling to Bob and the rest of engineering leadership. Victor should also document the migration path in detail: which BUILD files need to be written, which implicit dependencies need to be made explicit, what developer tooling changes are required. Making the migration concrete and bounded is what converts skeptics.

Where does your team actually sit on this?

This guide describes one level of one area. Run the assessment to place your team across all 16 areas, see which gates you have passed, and get a report you can take to your stakeholders.

Start the assessment