Introducing Bazel Remote Execution

banner
Matteo KammMatteo Kamm
4 MIN READ

Today we're launching Bazel Remote Execution, our solution for fast, multi-platform Bazel builds and tests. It runs your jobs across our fleet of high-performance machines, with observability built for both humans and agents from day one.

Bazel users have long sped up their builds with our remote caching, but many wanted more. Customers wanted to consolidate more of their Bazel workflows onto Namespace and kept asking why we didn't offer our own remote execution solution. So we built it.

How it works

Bazel breaks your build into actions and assembles them into a graph. It figures out which actions can run in parallel and hands them off to Namespace's scheduler that decides where each one runs. Our auto-scaled workers execute the actions, upload the finished artifacts to our CAS storage, and the results stream back to your machine.

Getting started is one command:

Command Line
$
nsc bazel setup --bazelrc=~/.namespace.bazelrc

That points Bazel at Namespace's high-performance platform. From there, you run your build or test as usual:

Command Line
$
bazel --bazelrc=~/.namespace.bazelrc test //...

A single invocation can fan out across the fleet, each running multiple units of work in parallel. Our zero-cost autoscaling brings that capacity up to meet peak demand and back down the moment they're idle, so you only pay for what you use.

Where the performance gains come from

Build speed is bounded by three things: how quickly a worker can get its inputs, how fast it can run the action once it has them, and whether it has to run the action at all. We tackled all three.

Bazel Remote Execution architecture on Namespace

The fastest (and cheapest) action is the one you never run. Everything on Namespace is content-addressed and shared, so work is never done twice. If you and a teammate kick off the same build concurrently, the two invocations join together and run once on the cluster. If CI builds a project and you later build something similar locally with remote execution enabled, you reuse whatever CI already populated.

When an action does have to run, its speed is bounded by how fast the worker gets its inputs, so on the storage side we built a tiered model. The hot tier is a cache volume inside the instance, backed by NVMe SSD. The warm tier catches hot-tier misses: if you're running across multiple data centers, or we can't locate your cache volume fast enough, we fall back to a tenant storage cluster on central storage nodes, also backed by NVMe SSD. In practice, that fallback delivered a noticeable performance gain, which is exactly why we built it.

Finally, the action has to execute fast. For the worker, we seamlessly integrate with our compute platform to use the highest single-core performance available across Mac, Linux, and soon Windows. We also added a layer of locality: when a worker runs an action, it hydrates the action's execroot from those storage tiers, and because the work has access to the hot tier, a similar action landing on the same worker usually finds its input already there. To hydrate the execroot incrementally, we built a custom user-space filesystem. This enables your action to start immediately instead of waiting for every input to materialize and delivers near-native performance while keeping each action isolated from others.

Bazel, but actually observable

Every build produces an invocation report, and we built it two ways at once: a UI that's easy for a human to drill into a build or test, and an API that dumps the same data straight to an LLM. The report pulls from the Build Event Protocol and correlates build events with our internal telemetry and the storage layer, so you get one coherent picture of what actually ran.

Accessing the report is one command away for an agent:

Command Line
$
nsc bazel invocation report <invocation-id>

Traditionally, understanding invocation performance has been painful. You either get a summarized view, or you have to stitch together separate data sources to piece together what happened. With an invocation report, you get a single view of every event: action queue times, action execution time, cache hits and misses, worker assignment, and much more.

So when a build fails or you spot a performance regression, you just point your agent at the invocation report. It gets everything we have and can usually reason about the issue without rerunning anything. And if it does need to reproduce the issue, remote storage already holds the intermediate artifacts, so it can pick up from a checkpoint and rerun just the failing action instead of the whole build.

What customers are seeing

Early access customers are seeing a range of performance improvement, from 25% to 100% faster than other managed and in-house solutions. Ramp was our design partner and earliest adopter, and now runs all of its Bazel builds and tests on Namespace.

Namespace's Bazel Remote Execution has unlocked new ways for us to build software in the agentic era. We've been early adopters and already see promising performance benefits.
JP Simard
JP SimardDirector of Mobile Engineering, Ramp

Many are also seeing much lower costs because of our worker cache model, our zero-cost autoscaling, and the fact that we don't charge for egress.

What's next

We're just getting started. Right now we route actions to any available worker; next we want to place them where their inputs already live, pushing data locality further. We're also exploring a way to explain and fix failed builds directly from the UI, so the agent loop lives right next to the dashboard.

Bazel Remote Execution is available today. Run nsc bazel setup to get started, or go check out our docs first.

Join 1,000+ of the world’s most ambitious companies