Skip to main content
With high parallelism on remote execution, Bazel can throttle execution on the client side while remote capacity sits idle: hundreds of actions ready to run, and a small fraction executing.

Symptoms

You’re likely hitting this if you see:
  • Many actions ready/queued, for example, 768 actions ready.
  • Only a small number actually running, for example, 72 actions running.
  • Abundant remote executor capacity, for example, 500+ container instances available.
  • Build profiles showing acquiringSemaphore traces.
  • Slower builds than expected despite high --jobs values.

Prerequisites

  • A working remote execution setup.
  • Bazel 7.0 or later.
  • High parallelism (for example, --jobs set to a multiple of host CPUs).

Diagnosing parallelization issues

To find out whether client-side throttling is limiting your build:

Step 1: Generate a build profile

Step 2: Force a rebuild

To avoid cache hits when profiling:

Step 3: Inspect the profile

Look for acquiringSemaphore traces. They mean Bazel is waiting on internal semaphores rather than using the remote executors.

Configuration

These Bazel flags reduce client-side throttling and raise concurrency. Put them in your workspace .bazelrc, in the rbe group that registers your exec platforms, so they apply only when a build executes remotely. RBE platforms shows how to turn that group on from the --config group aspect setup bazelrc writes, or from an Aspect CLI task.

Bazel flags

What each flag does:

Memory flags that cost incrementality

If the Bazel client runs out of memory at high parallelism, these flags reduce what the Bazel server holds: They cost warm incrementality: the next build on the same Bazel server re-analyzes from scratch. On Workflows runners, which keep the Bazel server and its analysis cache warm between jobs, that gives up most of what a warm runner saves. Use them only where the server isn’t reused, and fix memory with a larger client or --host_jvm_args first.

Job parallelism

A common pattern is a multiple of the host CPU count:
The exact multiplier depends on your workload characteristics and remote executor capacity.

Test and validation

To check the flags help:
  1. Run a clean build with profiling enabled:
  2. Check the build output to confirm more actions are running concurrently.
  3. Analyze the profile to verify that acquiringSemaphore traces are fewer or gone.
  4. Compare build times before and after applying these flags.

Before you keep a flag

  • Add flags one at a time. Profile after each and drop any that doesn’t help your workload, or that breaks the build.
  • Check your Bazel version. Flag behavior and support vary between Bazel releases; the release notes list known issues with experimental flags.
  • Check remote capacity. These flags remove client-side bottlenecks; the worker pool still needs the capacity for the extra actions in flight.