Setting up Bazel Remote Cache

Last updated: July 3, 2026

Why Bazel Remote Cache

A Bazel remote cache lets a team of developers and continuous integration (CI) systems share build outputs across machines. When builds are reproducible, outputs from one machine can be safely reused on another, which can make builds significantly faster. Bazel breaks a build into discrete steps called actions. Each action has declared inputs, output filenames, a command line, and environment variables.

The remote cache stores two types of data: an action cache that maps action hashes to result metadata, and a content-addressable store (CAS) of output files keyed by content hash. With a remote HTTP cache, Bazel can store and resolve action outputs across developer workstations, CI, and AI agent environments. In a typical setup, CI pipelines read from and write to the shared remote cache in every build (--config=ci), while developers and AI agents read from the cache without uploading new entries (--config=dev) because the CI environment is usually more reproducible. This action output caching model lets every machine benefit from work already done on other machines, saving up to 90% CPU time and CI costs in bill-per-time environments such as GitHub Actions CI.

Instead of recompiling, retesting, and repackaging on every machine, Bazel retrieves cached action outputs from the remote cache and reports them as remote cache hit in the build summary — turning work that takes minutes into cache lookups that finish in seconds or even milliseconds.

After CI populates the remote cache, a build on another machine can resolve most expensive actions from cache. In a typical scenario:

First build (CI populates the remote cache — say ~10 minutes):

$ bazel build //... --config=ci

INFO: Analyzed 45 targets (12 packages loaded, 234 targets configured).
INFO: Found 45 targets...
INFO: 45 processes: 45 internal.
INFO: Build completed successfully, 45 total actions in 10m 4s

Subsequent build (developer, AI agent, or fresh CI agent — ~4 seconds):

$ bazel build //... --config=dev

INFO: Analyzed 45 targets (0 packages loaded, 0 targets configured).
INFO: Found 45 targets...
[1/45] //dto:protobuf - cache hit
[2/45] //auth:lib - cache hit
[3/45] //api:lib - cache hit
...
INFO: 45 processes: 2 internal, 43 remote cache hit.
INFO: Build completed successfully, 45 total actions in 4s

Remote Bazel caching is especially valuable in ephemeral CI environments where CI agents are recreated on every run, and in actively developed monorepos where CI continuously warms the shared cache for the whole team. For safe sharing across machines, keep action inputs reproducible — for example, whitelist environment variables with --action_env so differing $PATH values do not reduce cache hit rates.

Configuring Bazel Remote Caching

Official Bazel Remote Caching documentation: https://bazel.build/remote/caching.

Bazel is quite flexible in configuring remote cache settings. BuildFetch's recommended approach is to keep cache flags in .bazelrc and control read-only/read-write behavior with .bazelrc groups:

build --remote_cache=https://token-auth:<TOKEN>@<CACHE_HOST>/<PROJECT_ID>/bazel/
build --remote_timeout=30

build:ci --remote_upload_local_results=true
build:dev --remote_upload_local_results=false

On CI, you can provide credentials through environment variables, for example:

export BUILDFETCH_BAZEL_REMOTE_CACHE_HOST="cache.example.buildfetch.com"
export BUILDFETCH_BAZEL_PROJECT_ID="project-id"
export BUILDFETCH_BAZEL_REMOTE_CACHE_TOKEN="..."
export BUILDFETCH_BAZEL_REMOTE_CACHE_URL="https://token-auth:${BUILDFETCH_BAZEL_REMOTE_CACHE_TOKEN}@${BUILDFETCH_BAZEL_REMOTE_CACHE_HOST}/${BUILDFETCH_BAZEL_PROJECT_ID}/bazel/"

bazel build //... --config=ci --remote_cache="${BUILDFETCH_BAZEL_REMOTE_CACHE_URL}"

For developer access, you can use a local token source (for example a shell profile or secret manager) and run Bazel with --config=dev so local builds read from cache without uploading:

export BUILDFETCH_BAZEL_REMOTE_CACHE_HOST="cache.example.buildfetch.com"
export BUILDFETCH_BAZEL_PROJECT_ID="project-id"
export BUILDFETCH_BAZEL_REMOTE_CACHE_TOKEN="..."
export BUILDFETCH_BAZEL_REMOTE_CACHE_URL="https://token-auth:${BUILDFETCH_BAZEL_REMOTE_CACHE_TOKEN}@${BUILDFETCH_BAZEL_REMOTE_CACHE_HOST}/${BUILDFETCH_BAZEL_PROJECT_ID}/bazel/"

bazel test //... --config=dev --remote_cache="${BUILDFETCH_BAZEL_REMOTE_CACHE_URL}"