Bazel Remote Caching: How to Configure, Verify, and Avoid Common Pitfalls
Discover how to set up Bazel’s remote cache, verify its use, and avoid common pitfalls such as non‑hermetic actions and TLS misconfiguration.
10 Sept 2026, 18:16 UTC

Why Enable Remote Caching?
When the same Bazel build runs on multiple machines or in successive CI steps, many actions produce identical outputs. Without a shared store, each machine recomputes those actions, wasting CPU time and slowing feedback. Remote caching lets Bazel upload the output of an action to a central repository and fetch it later, turning a rebuild into a download.
How the Cache Works
Every Bazel action declares its inputs, declared outputs, and the tools it invokes. Bazel hashes that declaration to produce a unique key. If the same key has been seen before, the output is already stored in the cache. The client then retrieves the output over gRPC; if the key is missing, Bazel runs the action locally and uploads the result if the upload flag is enabled.
Concrete Configuration Example
Add the following lines to a .bazelrc that applies to your workspace or CI environment. The example uses TLS; replace the URL with your own cache endpoint.
# .bazelrc
build --remote_cache=grpcs://cache.example.com:8980
build --remote_instance_name=main
build --remote_timeout=120
build --remote_upload_local_results=true
# Optional: specify the CA bundle if the server uses a custom root
build --remote_grpc_ssl_root_certificates=/etc/ssl/certs/ca-bundle.crt
Explanation of the flags:
--remote_cache– The gRPC endpoint of the cache service. Usegrpcs://for TLS.--remote_instance_name– A logical namespace that isolates your cache from other teams on the same server.--remote_timeout– Seconds to wait for a cache response before falling back to local execution.--remote_upload_local_results– Tells Bazel to upload successful local actions so they become available to other machines.--remote_grpc_ssl_root_certificates– Path to a PEM bundle containing the CA that signed the server’s certificate.
Before using the configuration, ensure the cache server is running and reachable. The service must present a TLS certificate that the client trusts, or you must provide the CA bundle as shown above.
Verifying Cache Hits
- Populate the cache: Perform a clean build so that all actions run locally and their outputs are uploaded.
bazel clean --expunge bazel build //my:target - Repeat the build: Run the same command again without cleaning.
bazel build //my:target - Look for cache hit messages: The console will contain lines such as
remote cache hitoraction cache hitfor actions that were served from the cache. - Measure time: Compare wall‑clock times of the two runs. A noticeable reduction indicates the cache is being used.
- Optional server metrics: If you have access to the cache logs or a metrics endpoint, check that upload and download counters match the number of actions executed.
Limits and Common Pitfalls
Remote caching only helps when actions are deterministic and hermetic. If an action writes a timestamp, uses a random seed, or reads a file that isn’t declared as an input, the hash will change and the cache will miss. Non‑hermetic tools can corrupt a build if a cached output is reused.
Network latency can also negate the benefit. Downloading a large binary over a slow link may take longer than compiling it locally. Consider using --remote_download_minimal to fetch only the files that are actually needed.
Typical mistakes include:
- Skipping
--remote_upload_local_resultsin CI: CI agents will read from the cache but never populate it, so the cache stays cold. - Misconfiguring TLS: If the client cannot verify the server’s certificate, the connection will fail. Verify connectivity with a tool such as
grpcurl:grpcurl -cacert /etc/ssl/certs/ca-bundle.crt grpcs://cache.example.com:8980 bazel.RemoteCache/GetCapabilities - Using non‑hermetic compilers: Compilers that embed build timestamps into object files break determinism. Configure the toolchain to strip volatile data or use a Bazel‑provided toolchain that guarantees hermeticity.
- Large outputs saturating bandwidth: Very large binaries or test logs can overwhelm the network. Splitting artifacts or storing them in a separate object store can mitigate this.
- Expecting speed‑ups for side‑effectful actions: Actions that write to undeclared external paths may produce cache hits but yield incorrect results. Audit BUILD files for undeclared outputs and mark them appropriately.
When Remote Caching May Not Be Worth the Effort
If your builds finish in a few seconds and most actions are cheap, the overhead of TLS handshakes and round‑trips can outweigh any benefit. Also, if build configurations change frequently (many --define flags or environment variables), the action hash will change often, reducing hit rates. In those cases, focus first on improving hermeticity and local incremental builds before adding a remote cache.
Practical Checklist
- Confirm the cache server is reachable and TLS is correctly configured.
- Add the
--remote_cacheand related flags to your.bazelrc. - Run a clean build to warm the cache.
- Run the same build again and look for
remote cache hitmessages. - Verify that the cache upload counter on the server increments after each local action.
- Audit BUILD files for non‑hermetic actions and undeclared outputs.
Conclusion
Remote caching can significantly reduce rebuild times when actions are deterministic and the network is reliable. By configuring the client with the appropriate flags, verifying cache hits, and avoiding common pitfalls such as non‑hermetic tools and TLS misconfiguration, teams can add a shared cache to both development and CI workflows with confidence.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.