Skip to main content
When an action has a cache miss in every cache, then it needs to be executed. Hopefully this execution is desirable and not just due to misconfiguration or non-determinism! Bazel executes actions in the Execution phase by spawning a subprocess, with an API like ctx.actions.run or ctx.actions.run_shell

Spawn strategies

Bazel can take several approaches to execute an action. Improvements to Bazel’s heuristics can make later releases faster without any changes to your code! See https://bazel.build/docs/user-manual#execution-strategy
  • sandboxed causes commands to be executed inside a sandbox on the local machine.
    • This requires that all input files, data dependencies and tools are listed as direct dependencies in the srcs, data and tools attributes.
    • Bazel enables local sandboxing by default, on systems that support sandboxed execution.
  • local causes commands to be executed as local sub-processes.
  • worker causes commands to be executed using a persistent worker, if available.
  • docker causes commands to be executed inside a docker sandbox on the local machine.
    • This requires that docker is installed.
  • remote causes commands to be executed remotely; this is only available if a remote executor has been configured separately.
  • dynamic is a special value to try both remote and local execution, take the first to complete.

Inspecting the sandbox

How to find it: run Bazel with the --sandbox_debug flag. It will print lots of extra information, and buried in there you can find paths beneath the temporary sandbox folder. This flag also causes Bazel to skip the cleanup and removal of the sandbox folder - leaving it available to inspect and troubleshoot.

Tuning resources per-action

Bazel has a heuristic-based scheduler that tries to maximize how much work can happen on the computer without overloading the system. Resources that might be overused:
  • RAM: Bazel schedules too many compilation actions and exhausts system memory, the OS swaps and the machine is unusable or hangs.
  • CPU: Bazel schedules too many intensive tests in parallel and they all fail to complete within their timeout because they run too slowly on a loaded system.
  • Network throughput: A mis-configured NAT gateway throttles outbound connections resulting in a hung container test.
Read more: bazel oom
For tests, simply adjusting the size attribute causes more RAM to be reserved. To reserve resources for build steps or to reserve CPU, use the resource_set API on the action spawn. See https://github.com/bazelbuild/bazel/issues/15187 however - this API is designed for a rule author rather than an end user. https://github.com/bazel-contrib/bazel-lib/blob/main/docs/resource_sets.md provides an easy way for rule authors to expose a string-typed resource_set attribute for targets to configure.