6.3.15 Multi-Region Remote Execution
extraPutting executors in several regions does not automatically make remote builds regional. The scheduler may still send an action to distant workers, its inputs may live in another CAS, and the consumer may have to fetch the outputs back across the same link. A multi-region design must place work and data together for the journeys it protects, then state what happens when a link or an entire region disappears.
This is a Bazel-specific placement problem built on ordinary distributed-systems design. 6.3.7 Remote Execution Storage supplies the publication invariant: the input closure must be available before execution, and a published result must refer to reachable output data. Here we decide in which region those conditions are satisfied and how they remain true during a partition or failover.
Start with the portable boundary
Bazel and the Remote Execution API give a deployment useful identities and contracts: an action and its Merkle input root, content digests, an instance name, remote service endpoints, and opaque platform properties. REAPI does not define geographic regions, choose the nearest one, replicate AC or CAS data, guarantee residency, or prescribe regional failover.1
Keep the portable surface separate from the regional implementation:
| Portable Bazel/REAPI fact | Regional contract the deployment must define |
|---|---|
| Action, command, input-root, and output digests | Which region may receive the action and each referenced blob |
instance_name and configured remote endpoints | Whether instances are regional, shared, replicated, or isolated, and how clients select them |
Opaque action Platform properties | Whether a pinned backend interprets a property as a region, pool, or locality hint, and what happens to an unknown value |
Execute, Operations, AC, CAS, and ByteStream requests | Which frontend, scheduler, storage replica, and executor serve each request and how their evidence joins |
A property such as region=europe-west is therefore not portable regional
routing. It becomes meaningful only when a versioned backend configuration maps
that value to a bounded compatible destination and visibly rejects or handles
unsupported values. The translation and placement proof follow
6.3.2 Remote Executor Matching; adding a region does not relax OS, architecture,
toolchain, image, or isolation compatibility.
An instance name is not a residency control either. It can select a logical namespace, but authorization, physical storage placement, replication, and deletion are deployment promises. Prove them through backend configuration, access tests, and storage observations rather than inferring them from the string sent by Bazel.
Choose a topology from the complete action journey
Draw one representative action from its client to its final consumer. Mark the client region, the selected frontend and scheduler, every CAS and AC read or write, the executor region, and the place where outputs are consumed. Then add the inter-region links explicitly. “Nearest executor” is useful only when the required inputs, compatible capacity, result publication path, and output consumer are also sufficiently near.
Four topology shapes expose different trade-offs:
Four deployment shapes compare one central execution region, paired active regions, a regional edge cache with central workers, and a self-contained regional execution island. Gold arrows represent control flow and blue arrows represent blob or result flow. Geography and failover are deployment contracts, not requirements of the Remote Execution API.
| Shape | Normal path | Main benefit | Cost or constraint to prove |
|---|---|---|---|
| One central execution region | All clients use one scheduler, CAS/AC, and worker fleet | One operational and consistency boundary; all workers can serve the same queues | Distant cache lookups, input/output transfer, and region-loss blast radius |
| Paired active regions | Clients read locally; writes and selected state are replicated; a remote read repairs a local miss | Local common-case reads plus continued service after one region is lost | Cross-region write latency, acknowledgement semantics, replication lag, and reduced capacity after loss |
| Regional edge cache with central execution | Clients use a nearby read-through cache, while remote misses and execution depend on the central region | Faster repeated reads without duplicating a worker fleet | Missing-input completeness checks and cross-region traffic on execution and cache misses |
| Regional execution island | A region has local frontend, scheduler, CAS/AC, and compatible workers; remote regions are consulted mainly for misses or replication | Local execution and a possible partition-tolerant regional path | Partitioned capacity, duplicated operations, regional data ownership, and reconciliation after recovery |
The last two shapes are easy to confuse. A read-through edge can improve cache latency while still sending execution inputs to a central worker fleet. A self-contained regional island can execute against its own source of truth, but cannot silently borrow remote workers during a partition. Dropbox's published case calls the latter a “super-edge” and contrasts it with an edge cache whose central execution path needs additional completeness checks.2
That case also shows a paired-metro pattern: local reads, synchronous mirrored writes, remote lookup on a local miss, and repair back into the local region. Treat those choices as one measured implementation, not as REAPI defaults. In particular, synchronous mirroring moves distance into the write path; asynchronous replication moves it into freshness and failover uncertainty. There is no universally correct choice without the workload's latency, availability, and data-loss requirements.
Buildbarn's Kubernetes deployment provides inspectable frontend, storage, scheduler, runner, and worker roles that can be assigned to failure domains, but it does not itself define a multi-region placement or replication policy.3 This is the right way to use an implementation topology: map concrete components and owners, then add and test the regional contract instead of reading geography into a Kubernetes manifest.
Make locality a measured placement decision
For each important action class, score a candidate region using the whole path:
- where the client, source upload, and current input closure are located;
- whether compatible and matchable executor capacity is available, including protected headroom after a region loss;
- expected AC lookup, CAS transfer, queue, execution, output upload, and local or downstream materialization time;
- which consumers need the result and whether they can read it under their own identities;
- residency and trust constraints on inputs, outputs, logs, and execution; and
- inter-region transfer, replicated storage, idle headroom, and operational cost.
6.3.12 Remote Execution Capacity explains why nominal executors or average CPU are not usable supply. In a regional design, calculate supply again after removing one region and its links. A failover destination that lacks the correct worker class, image, device, memory, or CAS access is not capacity for the affected actions.
Compare matched cohorts rather than two conveniently available builds. Hold the revision, target scope, configuration, platform and toolchain, action mix, cache temperature, client behavior, and output policy constant. For both the local and cross-region paths, retain:
- AC lookup latency and whether the result was local, replicated, or fetched remotely;
- input bytes and metadata served locally versus across the link;
- queue and compatible-placement time;
- command, output-upload, and result-publication time;
- output transfer or materialization to the real consumer; and
- cross-region bytes, tail latency, errors, retries, and total service cost.
A shorter executor distance can lose if inputs and outputs cross the region boundary. A slower remote miss may be acceptable when it leads to necessary execution, while a small delay repeated across a large cached action graph can dominate an otherwise warm build. The Dropbox case observed precisely this asymmetry between its latency-sensitive cached path and its more tolerant executed path.2
Specify partition and region-loss semantics before failover
Replication is a mechanism, not a failure contract. For every regional state population, state which copy is authoritative, when a write is acknowledged, what lag is allowed, what remains readable during a partition, and how divergent or incomplete state is reconciled. Apply the rule separately to CAS blobs, AC results, Operations, queues or leases, and audit evidence; they do not have the same durability or recovery semantics.
In particular, an AC entry must not become usable in a region before every CAS object needed by that result is reachable through the promised path. A replicated digest proves the identity of bytes, not that every region currently stores or may disclose them. Preserve the action, result, and blob digests when a failover exposes a miss or incomplete result.
Choose a degraded action policy explicitly:
- stay regional and queue or reject until local service returns;
- fail closed when residency, trust, or release policy forbids movement;
- execute in another region only after proving compatible capacity, input availability, authorization, and allowed data movement; or
- fall back locally only for action classes whose correctness and trust contract permits it.
Failover may create a second attempt while the first is still running or merely unobservable. Preserve Operation and backend-attempt identities, bound retry amplification, and define which terminal result may be accepted. Those attempt and cancellation rules belong to 6.3.13 Remote Action Failure Handling; geography does not make duplicate work safe.
Decide: The link from region A to region B fails. Region A can read a local
AC entry for an action, but one output blob named by its ActionResult exists
only in region B. Should region A report a cache hit, execute the action locally,
or route it immediately to region B?
Reveal
It must not report a usable hit: the result's required closure is unreachable. Preserve the result and missing-blob digests, then apply the declared degraded policy. Local regional execution is valid only if A has the complete inputs, compatible workers, authority, and capacity. Routing to B is impossible while the link is down and could violate residency even after it returns. The safe answer comes from the predeclared storage and placement contracts, not from the presence of an AC row.
Qualify the design with loss tests
Run the normal local and remote paths first, then inject one boundary loss at a time. At minimum test an inter-region partition, a lagging or missing CAS object, loss of the regional scheduler, and complete loss of one execution region. For each test, declare beforehand:
- which clients and action classes remain admitted;
- which data may cross the boundary and which must remain resident;
- which capacity and latency objective is protected at reduced scale;
- how queued and running attempts become known, failed, or explicitly unknown;
- whether AC/CAS reads and result publication remain complete; and
- how service returns to normal without accepting stale ownership or creating a cross-region retry storm.
Prove recovery with fresh clients in each affected region and with the real output consumers, not only service health checks. Planned topology changes use the drain, canary, and rollback discipline in 6.3.17 Remote Execution Upgrades. A coupled production incident across cache, execution, network, and regions continues in 6.6.6 Build-Service Incident Recovery; the whole deployment's qualification record is assembled in 6.3.18 Remote Execution Production Readiness.
Multi-region remote execution is a joined placement contract for actions, compatible capacity, AC/CAS data, and output consumers. Bazel and REAPI carry identities, instance names, platform properties, and service requests; the backend and deployment own geographic routing, replication, residency, partition, and failover semantics.
Choose a topology from matched end-to-end cohorts, not executor distance alone. Then state write acknowledgement, reachability, degraded execution, duplicate attempt, and recovery rules before a failure. A regional design is qualified only when partition and region-loss tests preserve complete results, allowed data movement, observable uncertainty, and enough matchable capacity for the protected journeys.
Check your understanding · 3 questions
1.Match each multi-region topology to its defining execution path:
Drag each answer onto the matching prompt, or click an answer and then click a prompt
2.Which conditions must hold before actions may fail over to another region?
Select all that apply
3.What is the soundest way to decide whether regional placement improves an action class?
Select one answer
Footnotes
-
Remote APIs — protocol contracts for caching and remote execution — portable action, instance, platform-property, service, digest, and result contracts versus backend-owned topology and policy ↩
-
Deploying High-Performance Remote Execution Setup in Multi-Region Topology - Ciprian Alexandru Pitis — Dropbox's single-metro, paired-metro, edge-cache, and regional “super-edge” architecture trade-offs ↩1 ↩2
-
bb-deployments — runnable Buildbarn topologies — Kubernetes component split as topology evidence without a portable multi-region policy ↩