NativeLink

Quickstart

Install NativeLink and point your build system at it in under 10 minutes.

Before you start

Nothing beyond a build system that speaks the Remote Execution API.

This guide takes you from zero to your first cached build. Pick the installation method that matches your platform, then wire your build system to the running cluster.

Prerequisites

You need a build tool that speaks the Remote Execution API: Bazel, Buck2, Siso, Pants, Goma, or CMake via recc. For the Docker path, Docker. For the Nix path, a recent Nix install with flakes enabled.

The fastest way is the prebuilt container image. It runs anywhere Docker runs; the configuration it needs is a single JSON5 file from the repository.

# Grab a known-good basic configuration
curl -O https://raw.githubusercontent.com/TraceMachina/nativelink/v1.6.5/nativelink-config/examples/basic_cas.json5

# Run the official image
docker run \
  -v $(pwd)/basic_cas.json5:/config \
  -p 50051:50051 \
  ghcr.io/tracemachina/nativelink:v1.6.5 config

The image is multi-arch: x86_64 and ARM64 both run natively (use v1.6.0 or later; earlier tags are x86_64-only). The server is now listening on localhost:50051.

curl -O https://raw.githubusercontent.com/TraceMachina/nativelink/refs/tags/v1.6.5/nativelink-config/examples/basic_cas.json5

nix run github:TraceMachina/nativelink/v1.6.5 ./basic_cas.json5

Slower than the prebuilt image because it builds from source, but works on macOS (Apple Silicon and Intel) and any Linux with Nix. Use it when you want a native binary instead of a container; the Docker path above also runs natively on Apple Silicon.

Invoke-WebRequest `
  -Uri "https://raw.githubusercontent.com/TraceMachina/nativelink/v1.6.5/nativelink-config/examples/basic_cas.json5" `
  -OutFile "basic_cas.json5"

docker run `
  -v ${PWD}/basic_cas.json5:/config `
  -p 50051:50051 `
  ghcr.io/tracemachina/nativelink:v1.6.5 config

The image is a Linux image published for x86_64 and ARM64, so Docker Desktop runs it on either kind of Windows machine. WSL2 with the Linux instructions above works too.

Verify it's running

In another terminal:

curl -v http://localhost:50051/

You should see the connection open and an HTTP response come back. The status will be an error, since / is not a gRPC route; the exact body doesn't matter, the connection succeeding does.

Point your build system at it

Add to your .bazelrc:

build --remote_cache=grpc://localhost:50051
build --remote_instance_name=main

Or pass them per invocation:

bazel build //... \
  --remote_cache=grpc://localhost:50051 \
  --remote_instance_name=main

Run any build target. Subsequent rebuilds of unchanged targets should report a remote cache hit count in the final processes: summary line. Leave --remote_executor off for now: the container image holds only the NativeLink binary, no shell or compilers, so actions sent to its worker cannot run. Remote execution sets up workers with a toolchain.

In your project root, add .buckconfig:

[buck2_re_client]
engine_address = localhost:50051
action_cache_address = localhost:50051
cas_address = localhost:50051
tls = false
instance_name = main

Then build as usual:

buck2 build //...

Buck2 also needs an execution platform with remote_enabled = True; the Buck2 page shows the one the checked-in integration test uses.

Set the endpoint variables Siso reads:

export SISO_REAPI_ADDRESS=localhost:50051
export SISO_REAPI_INSTANCE=main
export RBE_service_no_security=true   # only for local TLS-free dev

The Chromium build is the canonical Siso consumer; see Chromium for a full example.

In pants.toml:

[GLOBAL]
remote_cache_read = true
remote_cache_write = true
remote_store_address = "grpc://localhost:50051"
remote_instance_name = "main"

Then run any goal as usual; Pants will route through the cache.

Confirm cache hits

Re-run your build a second time without changing any source files. Every action should land in the cache and report a hit. With Bazel:

bazel build //... \
  --remote_cache=grpc://localhost:50051 \
  --execution_log_json_file=/tmp/exec.json

# Count the cache hits vs misses
grep -c '"remoteCacheHit": true' /tmp/exec.json

If you see hits, you're done. If not, jump to the troubleshooting section below.

Troubleshooting

FAQ

NextVerify your cache

A server that starts and a build that succeeds are not evidence that anything was cached. This is the line to read, and what it means when it says zero.

SidewaysConfiguration

What is in that JSON5 file, and how to grow it from a single node to a fleet.

SidewaysArchitecture

What each piece of the cluster is responsible for, and why the split is drawn where it is.

On this page