2.5 Execution Strategies

Execution-strategy settings route already-planned actions without defining a different target graph. For example, bazel build //app:server --spawn_strategy=sandboxed selects sandboxed execution as the default, while bazel build //app:server --strategy=Javac=worker,local routes Javac actions through a worker when that strategy can execute them. Otherwise, Bazel selects local. Across Bazel's strategy vocabulary, planned actions can run directly in the execroot, in a sandbox, through a long-lived worker process, on remote machines, or with local and remote branches competing.

The target graph from 2.1 Directed Acyclic Graph (DAG) has already become the action plan from 2.2.1 Loading, Analysis & Execution before strategy selection matters. The declared-input contract from 2.3.1 Hermeticity and action identity from 2.4.3 What Makes a Cache Hit must remain valid whichever execution environment Bazel chooses.

Read A Setting As Kind Plus Environment

2.5.1 Strategies Abstraction separates the action plan from execution policy. Analysis decides which actions exist, which inputs they declare, and which outputs they promise. Strategy decides where and under what constraints those actions run. A repository can therefore move from local builds to sandboxed CI, persistent workers, or remote execution without rewriting every BUILD file. If changing strategy changes the output bytes, the new environment exposed a hidden input, unstable tool, or another break in the action contract.

2.5.2 Strategies & Mnemonics names the two parts of a routing decision. Strategies such as local, sandboxed, worker, remote, and dynamic describe execution modes. Mnemonics such as Javac, CppCompile, and Genrule name action kinds. --spawn_strategy=sandboxed sets the default mode, while --strategy=Javac=worker,local routes one mnemonic through a specific strategy chain.

A concrete sandbox backend such as darwin-sandbox, linux-sandbox, or processwrapper-sandbox may appear behind the broader sandboxed choice. Project .bazelrc files may set these choices before you type a flag. 3.2 Project Configuration covers shared defaults and named configurations.

Treat An Override As An Experiment

If --strategy=Genrule=local makes a failure disappear, the action did not gain new build logic. The comparison usually exposes a dependency on the unconstrained host environment. Use 2.3.2 Sandboxing and 2.3.4 First-Response Debugging Flags to inspect that failure instead of making the local override permanent.

If a successful build reruns unexpected work, start with 2.4.4 Diagnosing Cache Misses instead. Strategy may be part of the eventual explanation, but the first evidence should match the symptom.

think

Decide: One build becomes faster after adding --strategy=Javac=worker,local. What hypothesis does that experiment test, and what evidence would justify keeping the strategy?

Reveal

The hypothesis is that repeated Java compile actions can amortize tool startup or initialization through a persistent worker. Compare repeated representative runs with the same target, flags, cache state, and edit scenario. Confirm in the profile that the expected execution cost falls, and verify that the tool supports the worker protocol while preserving hermetic, deterministic outputs. One faster run is not enough evidence for repository-wide policy.

Persistent workers and remote execution can change how actions run safely only when their meaning is already fixed. 6.3 Remote Execution and 6.5 Execution Strategies make those policies operational at scale.

key takeaway

Analysis defines the action, its mnemonic names the action kind, and the strategy chooses how that action runs. Local, sandboxed, worker, remote, and dynamic execution are policies over the same build model, not different ways to define the build.