3.6.5 Simple Remote Cache Setup

recommended

--disk_cache is the cheapest way to keep CI from repeating work, but it only helps the machine that owns that directory. Once builds run on multiple runners, or you want developer laptops and CI to reuse the same outputs, the cache has to live behind a network endpoint. Bazel's remote cache lets one machine upload action results and another machine download them instead of re-executing the same action.1,2 That makes it the natural next step after 3.6.4 Disk Cache in CI.

Why local disk cache helps one machine and remote cache helps many
Move the cache boundary from one filesystem path to one shared network endpoint
Cache boundary: one machine
LOCAL DISK CACHE
One machine owns the cache directory
Same filesystem path
--disk_cache=/var/cache/bazel
Hit
The next build reuses work only if it lands back on this same runner or laptop.
Limit
Another machine cannot see that directory, so the action runs again there.
Cheap and effective for one persistent machine.
Cache boundary: shared endpoint
SHARED REMOTE CACHE
One network endpoint serves many machines
Same URL from every machine
--remote_cache=https://cache.example.com
CI and developers meet here
CI
Uploads verified outputs
Writes shared results
build:ci
DEV
Reads shared hits
Downloads shared results
build:dev
DEV
Reads shared hits
Another machine, same cache
build:dev
CI writes an output once. Developer machines can then reuse that output elsewhere.
Local disk cache helps when the next build returns to the same machine. Shared remote cache helps when CI and developers need the same outputs from different machines.

When a Disk Cache Stops Being Enough

On a single persistent runner, --disk_cache is usually the right first move. The moment CI becomes stateless or horizontally scaled, local cache files stop being shareable: when the runner disappears, the cache disappears with it. For stateless workers, a remote cache is the recommended step once multiple workers need the same outputs.3 The same transition looks like this from another angle: a shared remote cache can be reused across branches, workspaces, developer machines, and CI build drones, which separates short-lived compute from persistent storage.4

If builds stay on one persistent runner, use 3.6.4 Disk Cache in CI. Move the cache to the network when stateless or multiple workers need to share results often enough to justify the service, access-control, and upload-policy overhead.

The Smallest Setup That Works

A remote cache needs only two things: a backend and one flag. The backend side is broad: any properly configured HTTP/1.1 server that supports PUT and GET can serve Bazel's cache protocol, and common options include bazel-remote, nginx, and object-store-backed services such as GCS.1 If you want the simplest purpose-built server on your own infrastructure, bazel-remote is the usual OSS choice: it stores data on disk, supports both REST and gRPC cache APIs, and includes garbage collection to keep storage bounded.5

The client side is just --remote_cache=. For a simple policy where CI writes and developers only read, a checked-in .bazelrc can be as small as:

build:ci --remote_cache=https://cache.example.com
build:dev --remote_cache=https://cache.example.com
build:dev --remote_upload_local_results=false

--remote_cache enables the shared cache. --remote_upload_local_results=false turns the client into a read-only consumer, which is the recommended way to keep write access narrow.6 HTTP and HTTPS work, and Bazel also accepts grpc and grpcs endpoints when your backend exposes those protocols instead.6 The ci-cache-baseline .bazelrc keeps these same lines as commented-out placeholders so the runnable example does not require a backend until a real endpoint, credentials, and a write policy actually exist.

For a concrete server route, the bazel-remote repository map starts with its standalone AC/CAS contract and then points to focused Docker Compose, Kubernetes, and systemd deployments.7 When an endpoint or error depends on protocol semantics rather than this server's configuration, move from that operational example to the authoritative remote_execution.proto through the Remote APIs repository map.8

Why the CI-Writes / Developers-Read Policy Matters

A shared cache multiplies good outputs, but it also multiplies bad ones. If a build action depends on something Bazel did not track correctly, one machine can upload an artifact that other machines will happily reuse. The classic example is an undeclared input: the build may "work" once, then spread a wrong result to every developer who shares the cache.4 Bazel's sandboxing reduces that risk substantially, but it does not make shared cache writes a free-for-all.4

That is why it pays to be careful about who can write to the remote cache, and why the simplest policy is still the best one for most teams: CI writes, everyone else reads.6 Keep the upload side tied to the environment you already treat as canonical, and let developer machines consume those artifacts without becoming another source of truth.

extra

Why Disk Cache and Remote Cache Feel So Similar

They are built on the same model. The remote cache has two stores: the Action Cache (AC), which maps an action key to an ActionResult, and the Content Addressable Store (CAS), which holds the actual output files by digest.1,9 Bazel's disk cache uses the same remote-cache concepts locally, which is why moving from --disk_cache to --remote_cache feels like changing the cache's location rather than learning a brand-new feature.2,9

A remote cache helps when the expensive part is re-executing unchanged actions on a different machine. It does not replace the server-state discussion in 3.6.2 Bazel Server Lifecycle in CI. Use it when execution work repeats across runners, then go deeper into protocol details, backend trade-offs, and cache isolation in 6.2 Shared Remote Cache.

key takeaway

Remote cache is the next step after --disk_cache when the cache boundary becomes the machine. Start with a single shared endpoint, let CI write, let developers read, and keep expectations realistic about what cache layer it accelerates. When you need protocol internals, namespace isolation, or production monitoring, continue in 6.2 Shared Remote Cache.

Check your understanding · 3 questions

1.Why is a CI-writes / developers-read policy recommended for shared remote cache write access?

Select one answer

2.True or false about remote cache setup:

Choose True or False for each sentence

An HTTP/1.1 server that supports PUT and GET can serve as a Bazel remote cache backend when it is configured to behave like Bazel's remote cache.
Setting --remote_upload_local_results=false makes a client read from the remote cache but not upload to it.
A remote cache eliminates the cold-analysis problem on fresh CI runners.

3.A team already uses --disk_cache on developer machines. They now want cross-runner sharing in CI. What is the recommended approach?

Select one answer

0 of 3 answered

Footnotes

  1. Remote Caching — remote cache as a shared backend, supported transports and backends, CI-only write guidance, and the note that CI containers still lose in-memory state 1 2 3

  2. Bazel's Remote Caching and Remote Execution Explained--remote_cache, combined cache with --disk_cache, and the lookup/execute/upload flow through AC and CAS 1 2 3

  3. How Bazel built its CI system on top of Buildkite — stateless workers cannot rely on local caches. Remote cache and bazel-remote as the next step

  4. Setting up a shared build cache using Bazel — why teams move from local to shared cache, benefits for CI/developers, and how cache poisoning spreads when inputs are undeclared 1 2 3

  5. Remote Cachingbazel-remote as a purpose-built cache server with disk storage, garbage collection, and REST/gRPC support

  6. Remote Caching--remote_cache, --remote_upload_local_results=false, supported http/https/grpc/grpcs schemes, and the recommendation to restrict write access 1 2 3

  7. bazel-remote repository map — the README and focused deployment files provide a purpose-built path from one cache process to a shared service

  8. Remote APIs repository map — the versioned Remote Execution proto is the authoritative AC, CAS, ByteStream, capability, and execution contract

  9. The Many Caches of Bazel — AC/CAS roles in the remote cache and disk cache as the same model used locally 1 2