NativeLink Documentation

repository·main·Indexed 23 days ago

https://github.com/tracemachina/nativelink

NativeLink (v1.6.3) is a high-performance build cache and remote execution system designed to accelerate software compilation and testing by distributing workloads and reusing build artifacts. It supports distributed deployments via Docker Compose, integration with Bazel, and observability through OpenTelemetry (OTEL) metrics, Prometheus, and Grafana.

Tokens
166K
Snippets
320
Records
746
Agent score
75%

What's inside NativeLink

  1. What is NativeLink?

    main

    NativeLink is a free and open-source simulation infrastructure platform written in Rust. It provides a Rust implementation of Bazel's Remote Build Execution (RBE) protocol and Content Addressable Storage (CAS).

    NativeLink is designed to be vendor-neutral and integrates seamlessly with several major build systems that implement the RBE protocol, including:

    • Bazel
    • Siso
    • Goma
    • Buck2

    Key design principles include:

    • Reproducibility and Hermiticity: Focused on mission-critical systems with native code.
    • Deterministic Execution: Does not use garbage collection to ensure predictable execution.
    • Performance and Safety: Leverages Rust's asynchronicity for high concurrency and memory safety.
    • Security and Transparency: Prioritizes scale, modern SBOM (Software Bill of Materials) transparency, and verifiability to protect the software supply chain.
  2. Overview of NativeLink

    main

    NativeLink is a high-performance, open-source remote build cache and execution platform written in Rust. It is designed for build farms and supports any client that implements the Remote Execution API.

    Supported Build Systems:

    • Bazel
    • Buck2
    • Siso
    • Pants
    • BuildStream
    • Goma
    • CMake (via recc)

    Key Characteristics:

    • High performance, designed for massive scale (battle-tested on over a billion build requests a month).
    • Supports Local Remote Execution (LRE) for hermetic builds without Docker.
    • Available as a self-hosted platform or via a paid Enterprise tier.
  3. Use NativeLink with other build systems

    main

    NativeLink implements the standard Remote Execution (RE) API. If your build tool supports this protocol, you can integrate NativeLink as a CAS (Content Addressable Storage), Action Cache, and executor without rewriting your build files.

    Supported integrations include:

    • Buck2: Use Buck2's built-in remote execution client with NativeLink as CAS, Action Cache, and executor.
    • Siso: Configure Chromium's Ninja replacement to use NativeLink through the RE API.
    • Pants: Enable remote cache reads and writes via pants.toml.
    • BuildStream: Point BuildStream artifact storage and remote execution at NativeLink.
    • CMake with recc: Wrap CMake compile actions with recc to share compile outputs through NativeLink.
  4. Understand NativeLink core concepts and terminology

    main

    To use NativeLink effectively, you should understand its core vocabulary regarding build execution and storage:

    Build Execution

    • Action: The fundamental unit of work. It encodes a command line, input file digests, platform requirements, and expected outputs. Hashing an action produces a stable identifier.
    • ActionResult: The result of an action, containing output file digests, exit codes, captured stdout/stderr, and timing metadata.
    • Worker: The process that executes an action. It is responsible for fetching inputs from the CAS, running the command, and uploading outputs back to the CAS.
    • Scheduler: The dispatcher that receives Execute calls, selects appropriate workers, and tracks in-flight actions.
    • LRE (Local Remote Execution): A mode where NativeLink runs on localhost using a Nix-pinned toolchain, ensuring local builds are bit-identical to remote ones.
    • Hermetic build: A build where outputs depend strictly on declared inputs, ensuring identical results across any machine at any time.
    • Toolchain: The bundle of binaries (compiler, linker, etc.) required for an action to run.

    Storage and Identification

    • Digest: A combination of a content hash and a size. NativeLink uses digests instead of file paths for identification.
    • CAS (Content-Addressable Storage): A storage system where every blob (source files, intermediate outputs, binaries) is stored under its SHA-256 hash. Identical byte sequences result in a single entry.
    • Action Cache (AC): A keyed store mapping hash(Action) → ActionResult. A cache hit allows the system to skip the work entirely.

    Infrastructure and API

    • RE-API (Remote Execution API): The standard gRPC protocol used by supported build systems to communicate with NativeLink.
    • Instance name: A namespace within a NativeLink cluster. Action hashes from different instance names are isolated and do not collide.
    • Platform properties: Key/value tags (e.g., Linux, x86_64, GPU) attached to actions and workers. The scheduler uses these to match actions to compatible workers.
  5. What is Local Remote Execution (LRE)?

    main

    Local Remote Execution (LRE) provides the hermeticity of Remote Build Execution (RBE) while maintaining local iteration speeds. It allows you to run a remote-execution worker on your local machine using a Nix-pinned toolchain.

    Key Benefits:

    • Bit-identical artifacts: The Nix-pinned toolchain ensures identical output across different machines and CI.
    • Real hermeticity without Docker: Avoids container runtime overhead and image rebuilds.
    • Cache sharing: Because action hashes match between local and remote workers, a cache hit in one location is a cache hit everywhere.
    • Offline capability: Once the toolchain is fetched, LRE operates as pure local computation.
  6. What is Local Remote Execution (LRE)?

    main

    NativeLink's Local Remote Execution (LRE) is a framework designed to build, distribute, and iterate on custom toolchain setups that are transparent, fully hermetic, and reproducible across machines with the same system architecture.

    LRE mirrors toolchains used for remote execution within your local development environment. This allows developers to reuse build artifacts with a high cache hit rate across different repositories, developers, and CI environments.

    Note: Currently, LRE only supports x86_64-linux and is considered highly experimental.

  7. Understanding NativeLink Instance Names

    main

    An instance name acts as a namespace within a NativeLink cluster.

    • Isolation: Action hashes from different instance names do not collide, allowing a single deployment to serve multiple isolated teams.
    • Requirement: Both the client and the server must be configured with the same instance name. A mismatch will result in the client seeing a permanently empty cache, even if the work has been done under a different name.
  8. Understand NativeLink deployment roles

    main

    A NativeLink deployment consists of four distinct roles. While a single binary can run all four roles simultaneously, for production environments, you should run them as separate processes to allow for independent scaling and restarts.

    RoleDescriptionStatefulness
    CAS serverStores and serves content-addressed blobs.Stateful
    AC serverMaps Action digests to ActionResults.Stateful
    SchedulerReceives Execute calls and dispatches them to workers.Stateless
    WorkerRuns actions in a sandbox and uploads outputs to the CAS.Stateless
  9. Combining wire compression with the dedup store

    main

    You can combine wire compression with a dedup store, but you must understand the order of operations:

    • Wire compression is undone at the gRPC boundary before the bytes reach the storage layer.
    • Deduplication must operate on raw content. If you were to attempt deduplication on compressed bytes, identical chunks would appear different due to compression variations.

    Because NativeLink decompresses at the boundary, the dedup store correctly sees the raw content and functions as expected.

  10. How Local Remote Execution works

    main

    LRE relies on the collaboration of three components:

    1. NativeLink worker: Runs on the developer's machine, bound to the loopback interface.
    2. Pinned toolchain: Provided by a Nix flake. Every binary (compiler, linker, coreutils, etc.) is content-addressed in the Nix store.
    3. Configured client: A build tool (like Bazel or Buck2) configured to target the local worker using the same protocol used for remote clusters.

    When a client issues an Execute call, the action's inputs are fetched from a local Content Addressable Storage (CAS) running on localhost. The worker executes the command in a sandbox using the pinned toolchain, and the outputs are stored back in the CAS via a Unix socket instead of a network connection.

  11. Common NativeLink endpoint configuration

    main

    When configuring external build tools to connect to NativeLink, the standard endpoint configuration assumes the server exposes CAS, Action Cache, execution, capabilities, and ByteStream on port 50051 with the instance name main.

    Important Note on Instance Names: Action hashes computed under different instance_name values never collide. A mismatch between the client's instance name and the server's exposed instance name will not produce an error, but it will result in a cache that appears permanently empty. Every client targeting a cache must send the exact same instance_name that the server exposes.

  12. How NativeLink wire compression works

    main

    NativeLink implements wire compression at the gRPC boundary. This means:

    • Storage is unaffected: The CAS (Content Addressable Storage) stores raw, uncompressed bytes. Existing read paths see ordinary blobs.
    • Resource names and digests: These always refer to the uncompressed blob. Only the bytes on the wire are compressed.
    • Verification: NativeLink hashes the decoded bytes during upload. It rejects any blob where the decompressed content does not match the expected digest or size.
    • Efficiency: Batch reads automatically fall back to identity (uncompressed) transfers if the zstd encoding would not result in a smaller payload, preventing unnecessary CPU overhead for incompressible blobs.
    • Compatibility: It is safe to enable in a mixed environment. Clients that do not support or request compressed-blobs/zstd will continue using identity transfers.