> ## Documentation Index
> Fetch the complete documentation index at: https://namespace.so/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Bazel cache

export const CenteredImage = ({src, alt, width, caption, className}) => {
  const [basePath, setBasePath] = useState("");
  useEffect(() => {
    const path = window.location.pathname;
    setBasePath(path === "/docs" || path.startsWith("/docs/") ? "/docs" : "");
  }, []);
  return <Frame caption={caption} className={className} style={{
    maxWidth: width,
    marginInline: "auto"
  }}>
			<OptimizedImage src={`${basePath}${src}`} alt={alt} />
		</Frame>;
};

Reuse Bazel build artifacts across runs. The cache is shared between your CI
workflows and local builds.

Namespace provides high-performance [Bazel](https://bazel.build) caching with
very low network latency between runners and the cache storage. This allows your
Bazel workflows to reuse build artifacts across runs, irrespective of your
chosen granularity, significantly reducing build times.

Bazel caching is particularly effective for:

* Build steps that are time-consuming to execute
* Projects where compilation is typically slow, such as Rust and C++ codebases
* Workflows that can benefit from cross-invocation artifact reuse

Since the cache is shared, local builds can also benefit from artifacts already cached by CI, and vice versa.

## Getting started

Bazel caching is a paid add-on. In order to enable it for your workspace contact [our sales team](mailto:sales@namespace.so).
You can produce a ready-to-use configuration with [`nsc bazel setup`](/docs/reference/cli/bazel-setup):

<Steps titleSize="h3">
  <Step title="Configure cache access">
    ```bash theme={null}
    nsc bazel setup --remote=false --bazelrc /etc/bazel.bazelrc
    ```

    This command generates short-term credentials and sets up a `bazelrc` configuration file.
  </Step>

  <Step title="Use the Bazel cache">
    ```bash theme={null}
    bazel --bazelrc=/etc/bazel.bazelrc test //..
    ```

    You can pass multiple configuration files by setting `--bazelrc` repeatedly, allowing you to combine your existing configuration with Namespace cache access.
    See [Bazel's documentation](https://bazel.build/run/bazelrc) for granularity control options.
  </Step>
</Steps>

### GitHub Actions Example

<Steps titleSize="h3">
  <Step id="configure-cache-access-2" title={<span>Configure cache access</span>}>
    When using Namespace runners, you can enable Bazel caching directly in your [profile configuration](https://cloud.namespace.so/workspace/actions/profiles).

    <CenteredImage width={600} alt="Bazel caching enabled in a Namespace runner profile" src="/docs/images/bazel/bazel-profile-enable-caching.png" />
  </Step>

  <Step id="use-the-bazel-cache-2" title={<span>Use the Bazel cache</span>}>
    In your workflow, you only need to select the corresponding profile. Bazel is already configured to use the Namespace cache.

    ```yaml {3} theme={null}
    jobs:
      build:
        runs-on: namespace-profile-with-bazel
      steps:
        - name: Bazel test
          run: bazel test //..
    ```
  </Step>
</Steps>

## How it works

The Bazel caching solution employs a tiered caching approach, where the hot cache lives as close to the consumer (e.g. your CI job runner) as possible.
The cold caching tier is backed by our [high-performance artifact storage](/docs/architecture/storage/artifact-storage) and enables Bazel to retain a vast amount of cached artifacts.

Access to the Bazel cache is granted through short-lived secure credentials.

## Usage

Namespace accounts Bazel cache usage in two categories:

* Bazel cache storage
* Bazel cache reads

For detailed billing information for each item as well as included amounts in your plans,
visit [the pricing page](https://namespace.so/pricing).

## Remote Asset API

Namespace implements Bazel's
[Remote Asset API](https://github.com/bazelbuild/remote-apis/blob/main/build/bazel/remote/asset/v1/remote_asset.proto),
which lets Bazel offload external downloads to the Namespace cache instead of fetching them directly from the origin.

Namespace's remote Bazel caches support:

* **Checksum-verified fetches** using the `checksum.sri` qualifier (SHA-256).
  When Bazel provides an integrity hash, Namespace resolves the asset straight
  from cache without contacting the origin.
* **Custom HTTP headers** via the `http_header:` and `http_header_url:`
  qualifiers, so authenticated or header-gated downloads work through the cache.
* **HTTP and HTTPS URIs.**

### Enabling

The remote Asset API is opt-in. When using Namespace runners, enable it in your
[profile configuration](https://cloud.namespace.so/workspace/actions/profiles)
alongside Bazel caching. The generated `.bazelrc` will contain the necessary flags automatically,
so you only need to select the profile:

```yaml {3} theme={null}
jobs:
  build:
    runs-on: namespace-profile-with-bazel
  steps:
    - name: Bazel test
      run: bazel test //..
```

When configuring the cache with the [CLI](/docs/reference/cli/installation), pass the `--enable_remote_asset_api` flag to include the remote asset endpoint in the generated bazelrc:

```bash theme={null}
nsc bazel setup --remote=false --enable_remote_asset_api --bazelrc /etc/bazel.bazelrc
```

## Running Bazel from a Devbox

You can create a [Devbox](/docs/devbox) with Bazel caching already configured.
Namespace runs the setup for you, so `bazel` uses the Namespace cache without any
further steps.

<Steps titleSize="h3">
  <Step title="Enable Bazel caching">
    Turn on caching when you create the Devbox, and select the repository holding
    your Bazel project at the same time. The Devbox then starts with the repository
    cloned and the cache configured, ready to build.

    <Tabs>
      <Tab title="Create wizard">
        Create a new Devbox from the [Devboxes](https://cloud.namespace.so/workspace/devboxes) page and select your repository. Expand the **Advanced** section and turn on **Bazel cache**.

        <CenteredImage width={600} alt="Bazel cache toggle in the Advanced section of the Devbox create wizard" src="/docs/images/bazel/dashboard-create-enable-bazel.png" />
      </Tab>

      <Tab title="Blueprint">
        Use a [Blueprint](/docs/devbox/blueprint) so every Devbox created from it has caching configured. Set the repository in the **Repository** dropdown, then find the **Integrations** section and turn on **Bazel**.

        <CenteredImage width={600} alt="Bazel toggle in the Integrations section of a Devbox blueprint" src="/docs/images/bazel/dashboard-blueprint-enable-bazel.png" />
      </Tab>
    </Tabs>

    To add caching to a Devbox that was created without it, open a shell in the
    Devbox and run setup against the same path the toggle configures:

    ```bash theme={null}
    nsc bazel setup --bazelrc=/home/devbox/.bazelrc --remote=false
    ```
  </Step>

  <Step title="Run Bazel from the Devbox">
    Open a shell in the Devbox:

    <Tabs>
      <Tab title="Devbox CLI">
        ```bash theme={null}
        devbox ssh my-devbox
        ```
      </Tab>

      <Tab title="Dashboard">
        Open the terminal on your Devbox from the [Devboxes](https://cloud.namespace.so/workspace/devboxes) page.

        <CenteredImage width={600} alt="Terminal on a Devbox in the Namespace dashboard" src="/docs/images/bazel/dashboard-devbox-terminal.png" />
      </Tab>
    </Tabs>

    Then build as you normally would:

    ```bash theme={null}
    bazel build //...
    ```

    You do not need a `--bazelrc` flag. Namespace writes the configuration to
    `/home/devbox/.bazelrc`, which is the `devbox` user's home `bazelrc`, so Bazel
    picks it up automatically.
  </Step>
</Steps>

The Devbox also sets a `BAZELRC` environment variable pointing at that file.
Use it when you need to name the configuration explicitly, for example from a
script or a Makefile that combines it with your own configuration:

```bash theme={null}
bazel --bazelrc=$BAZELRC --bazelrc=tools/bazelrc/rbe.bazelrc build //...
```

The same applies to commands run with [`devbox exec`](/docs/devbox/exec), which
is the usual way to drive builds from CI or from a coding agent:

```bash theme={null}
devbox exec my-devbox -- bazel build //...
```

To also run the Bazel actions on Namespace compute, see
[Remote Execution from a Devbox](/docs/bazel/execution#remote-execution-from-a-devbox).

## Bazel cache from GitHub-hosted runners

You can use the Namespace Bazel cache from GitHub-hosted runners. This lets you validate your cache setup before migrating your runners to Namespace.

<Info>
  Performance in this setup is not representative of running your full workflow on Namespace.

  From GitHub-hosted runners, cache reads and writes travel over the public internet, adding latency you won't see once your runners run on Namespace.
</Info>

Use [Identity Federation](/docs/federation/github-actions#from-github-runners) to grant GitHub Actions access to the Namespace Bazel cache and other resources.

**Example**
A minimal workflow that configures cache access looks like this:

```yaml theme={null}
name: Example workflow
permissions:
  id-token: write # This is required for federation using OpenID Connect
  contents: read # This is required for actions/checkout
jobs:
  test:
    name: Bazel test
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Configure access to Namespace
        uses: namespacelabs/nscloud-setup@v0
      - run: |
          nsc bazel setup --remote=false --bazelrc /etc/bazel.bazelrc
```

For a full step-by-step walkthrough, see [From GitHub Runners](/docs/federation/github-actions#from-github-runners) in the Federation documentation.

## Observability

Namespace records the invocations that run through the cache. Inspect them from
the [Bazel invocations](https://cloud.namespace.so/workspace/bazel/invocations)
page or with `nsc bazel invocation list`. See
[Bazel observability](/docs/bazel/observability).

<h2 id="remote-build-execution">
  Bazel Remote Execution
</h2>

Beyond caching, Namespace can run your Bazel actions on Namespace compute,
scaling builds horizontally with high parallelism. Remote Execution uses this
cache, so remotely executed actions share artifacts with your CI and local
builds.

[Learn more about Bazel Remote Execution →](/docs/bazel/execution)
