2.4.3 What Makes a Cache Hit

A cache hit in Bazel means more than "the file already exists." Bazel asks whether a specific action is the same computation as before: the same declared inputs, the same instructions for producing outputs, and the same relevant execution context. When that identity matches, Bazel can safely reuse outputs instead of rerunning the action.1,2,3

Will this action be a cache hit or a cache miss?
Bazel computes one key and performs one lookup for each action — not for the target as a whole
INPUTS
Declared source files and generated inputs
The files this action reads
INSTRUCTIONS
The command line and action metadata Bazel records
Command line and action metadata
EXECUTION CONTEXT
Relevant configuration, declared environment, execution platform, and declared tools
Context that can change the action
ACTION KEY
Bazel combines those buckets into one action identity
Same identity → eligible to reuse outputs
ACTION CACHE
Bazel looks up the action key before executing
Local action metadata or shared cache
HIT
A matching entry identifies the saved outputs
Restore the outputs and skip execution
OR
MISS
No usable entry exists for that key
Run the action and record the result
Think action identity, not the target label alone: change inputs, command, or context and the key changes, so reuse follows the fine-grained work units Bazel actually runs.

Cache hits are action-level

That boundary lives below the top-level target. One target often expands into several actions: compiles, archives, links, code generators, test runners. Bazel caches the resulting artifacts, not "the fact that //app:server ran", which is the artifact-based model from P.2.1 Task-Based vs Artifact-Based.3,4

A Make-style mental model is too weak here. Task-based systems mostly reason from tasks and file timestamps, so command or environment changes are easy to miss. Bazel records the action definition itself, which is why changing compiler options or other configuration can invalidate work even when the source files did not change.5,6

That is why building the same label under different configurations can legitimately produce different compile or link outputs. The label may be the same, but the action definition is not.1,5

What goes into the key

For Level 2, use a three-part checklist: inputs, instructions, and execution context.

  • Inputs: declared source files and generated files consumed by the action. Remote caching works because Bazel knows those inputs explicitly and can reuse outputs only when the same input state is seen again.2,7
  • Instructions: the command line and other action metadata that define what tool Bazel is asking to run.1,4
  • Execution context: build flags, action environment variables, and target platform are part of configuration. Tools and toolchain files participate separately because Bazel treats tools as dependencies too.1,3
extra

The internal names you may meet later

If you inspect bazel dump --action_cache in 5.7 Cache & Execution, you will see names like actionKey, usedClientEnvKey, and digestKey. You do not need to memorize them for Level 2. The useful point is that Bazel tracks non-file metadata, environment, and file digests separately when deciding whether an on-disk output is still valid.7

Why hermeticity decides whether the key is trustworthy

A normal cache miss only costs time. A false cache hit is worse, because it reuses the wrong bytes. That is why hidden inputs are dangerous: if an action depends on host state Bazel did not record, the key no longer fully describes the real computation.8

There are two practical leak paths worth calling out. Environment variables can reduce cross-machine hits when different machines smuggle different values into an action definition, and tools outside the workspace can produce different outputs even though Bazel did not track the tool itself as an input.2 Real cache-miss investigations show the same pattern with $PATH, host compilers, and non-deterministic files generated by repo rules or package managers.9,10

That is the bridge back to 2.3.1 Hermeticity. Hermeticity is not a separate optimization from caching. It is what makes the cache key meaningful in the first place. When a build keeps rebuilding unexpectedly, 2.4.4 Diagnosing Cache Misses is the first-response tool at this level. When you later need action-by-action proof, 5.7 Cache & Execution is the deeper debugging chapter.2,8

key takeaway

A cache hit means Bazel proved "same action, same result," not just "same target name" or "newer file." Think in terms of declared inputs, command/config/env, and tools: change any of those, and a rebuild is usually correct. Leave them stable and Bazel can safely reuse outputs across commands, checkouts, and even machines.1,2,3

Check your understanding · 3 questions

1.A developer changes only compiler flags, not any source files. Should Bazel reuse cached action outputs from the previous build?

Select one answer

2.Which factors are included in Bazel's action cache key?

Select all that apply

3.True or false: cache key correctness and hermeticity.

Choose True or False for each sentence

If an action reads a host file that Bazel did not declare as an input, the cache key no longer fully describes the real computation.
A task-based build system using file timestamps provides equivalent cache-hit accuracy to Bazel's action-key model.
0 of 3 answered

Footnotes

  1. Bazel Glossary — definitions of action, action key, action cache, and configuration 1 2 3 4 5

  2. Remote Caching — action inputs, output names, command line, environment, Action Cache lookup, and env/tool leakage caveats 1 2 3 4 5

  3. Artifact-Based Build Systems — artifact-based model and treating tools as dependencies 1 2 3 4

  4. Bazel and action (non-) determinism — one target expanding into multiple actions and action identity as command, input hashes, and environment configuration 1 2

  5. Build programs with Bazel — correct incremental rebuilds depend on matching inputs and command/config, not only file freshness 1 2

  6. Task-Based Build Systems — timestamp/task model and why command or environment changes are easy to miss

  7. The Many Caches of Bazel — output-tree actionKey, usedClientEnvKey, digestKey, and remote Action Cache lookup 1 2

  8. Hermeticity — hidden inputs, host-state leaks, and why reproducibility underpins caching 1 2

  9. Diagnosing Bazel Cache Misses — non-deterministic repository rule outputs becoming downstream inputs and causing misses

  10. .bazelrc flags you should enable$PATH and other environment leaks causing large cache misses