Fleet

Regions

Pin a tenant to a region, so that its jobs, histories and payloads stay with that region's edges, nodes, Temporal and payload store.

For: cluster operators.

Configure regions when jobs must run on selected nodes or near an edge. Check the effects on routing before moving a tenant.

A region is a name you give to edges. A cluster can hold several: tenants in eu beside tenants in us, with one management, one set of people and one plugin index. Each tenant is pinned to one region, and its work stays there:

  • its jobs run only on its region's nodes, through its region's edges;
  • its Temporal histories are on its region's Temporal backend;
  • its payloads (large inputs and outputs, files, results kept out of the histories) are in its region's payload store;
  • its model calls go only to providers in its region, unless its data rules name other regions.

A cluster that names no region has one, the unnamed region, and works as it always did. Nothing on this page changes it until you start an edge with --region.

What a region is made of

PartHow it gets its region
Edgesoz0 server start --region eu. An edge serves only the tenants of its region and admits only nodes that joined in it.
Temporal backendsThose the region's edges reach: their --temporal-* flags and their backends file. A backend's name means the backend of the tenant's region, so default in eu and default in us are two Temporal services. An entry of the backends file may say region: eu; an edge of another region then refuses to start with it.
Payload storeThe --payload-store bucket or OZ0_PAYLOAD_DB database the region's edges write to (Payload storage). Every edge of a region names the same one, and two regions never share one.
NodesA node is in the region of the edge it joined through. oz0-node join --region eu only checks it: the join fails if --server is an edge of another region. A node never changes region; remove it and join it again.
Tenantsoz0 tenant create nordic --region eu, or a move (below).

Run management apart from the edges when you use regions (Run the roles separately): management serves every region, and an all-in-one server is one region.

Set up two regions

Terminal
# In eu: edges with their own Temporal and their own bucket.
oz0 server start --roles=edge --region eu --management-url https://mgmt.example.net:8443 \
  --temporal-backend external --temporal-address temporal.eu.internal:7233 \
  --payload-store 's3://oz0-eu/payloads?region=eu-north-1' ...

# In us: the same, with us's Temporal and bucket.
oz0 server start --roles=edge --region us --management-url https://mgmt.example.net:8443 \
  --temporal-backend external --temporal-address temporal.us.internal:7233 \
  --payload-store 's3://oz0-us/payloads?region=us-east-1' ...

oz0 tenant create nordic --region eu
oz0 token create --tenant nordic          # then join nodes through an edge in eu

A cluster that already runs gives its unnamed region a name first, so that its tenants and nodes keep working under it. Naming the region pins every tenant in it, and a pinned tenant's model calls go only to providers in its region when its data rules name none (in this guide). The built-in Anthropic and OpenAI records say us, and a record that names no region (such as one made from the OpenRouter preset) passes no region at all, so naming the region eu would refuse those calls from then on, in running jobs too. Look first:

Terminal
oz0 region name eu --dry-run
# Naming the unnamed region eu would move 2 tenant(s) and 4 node(s) to it. Nothing changed.
# Model calls that would be refused, because these tenants' data rules name no region and so allow only providers in eu:
#   tenant default: providers anthropic, openai; aliases smart (no target left)

# Keep them: name the regions the tenant's calls may go to, or say where a provider runs.
oz0 model rules --tenant default --region eu --region us --reason "providers in us, as before regions"
oz0 provider set my-router --tenant default --region us   # a record that named no region

oz0 region name eu --reason "a second region joins the cluster"
# then restart the existing edges with --region eu

Until the edges' region and the tenants' agree, those tenants' work waits: Temporal keeps it, and nothing is lost. oz0 doctor warns of a pinned tenant whose aliases have no target its region allows.

What the edges refuse

CallThrough an edge of another region
A node's join, renewal, control stream or Temporal callRefused with the node's region. A node's list of edges to fail over to names only its own region's edges.
An app's or a person's call about the tenant (the runtime API, MCP, A2A)Refused with FailedPrecondition: tenant nordic runs in region eu ... send its requests to an edge of eu, with the region in the Oz0-Tenant-Region response header. The console's calls through management go again to an edge of the tenant's region by themselves, and management sends MCP and A2A calls, whose paths name the tenant, to an edge of its region at once.
A Temporal call the edge itself would make for the tenantNever leaves the edge.

Model calls stay in the region

When a tenant is pinned to a region and its data rules name no region, the gateway allows only providers in that region: a provider record in eu-north passes a tenant in eu, and one whose record names no region passes none.

Terminal
oz0 model rules --tenant nordic
# Tenant nordic's data may go: only in eu, the tenant's region.

oz0 provider set anthropic --tenant nordic --region eu   # a provider record the tenant's calls may use
oz0 model rules --tenant nordic --region eu --region us  # or allow more, as a governed change with a reason

Move a tenant to another region

Terminal
oz0 tenant region nordic --set us --reason "the customer moved"
oz0 token create --tenant nordic                  # then join its nodes in us, through an edge in us
oz0 tenant region nordic                          # follow the move until it is done
# Tenant nordic is in region us.
# Last move: Tenant nordic: region eu -> us, done at 2026-10-13 14:02.

From the moment of the move:

  • new work goes to the new region: its edges start the tenant's jobs on their Temporal backend, write its payloads to their store, and admit its nodes there. A node joins only in its tenant's region, so the tenant's nodes in the new region join once the move started; until one runs, its new jobs wait in the new region's Temporal;
  • the jobs that run finish in the old region, whose edges serve only those: their nodes' tasks, lookups, approvals and cancels. They refuse every new job of the tenant, naming the new region (a webhook, a routine's webhook or an event delivery gets 421 Misdirected Request with the region in the Oz0-Tenant-Region header), routines' fires among them (run now, a backfill, an event's fire and a schedule's fire that is still due there), and delete its routines' schedules there; the new region's edges make them again. A start through management goes to the new region by itself;
  • its model calls follow: when its data rules name no region, they now allow only providers in the new region, so give it provider records there (oz0 provider set ... --region us) before its new jobs call a model. The move's answer lists the providers and aliases the tenant loses;
  • the move ends once nothing of the tenant runs in the old region and every edge there has applied the move. The old region's edges then serve nothing of the tenant.

Nothing is copied. The tenant's closed histories and payloads stay in the old region until that region's retention removes them, and after the move they are not reachable through the API; export the tenant first if you need them.

A move is refused while the tenant moves between Temporal backends, while another region move drains, and when no live edge of the target region knows the tenant's backend. If no edge of the old region is up at the moment of the move, it ends at once: jobs that waited there go on only if the tenant moves back.

Only cluster admins move tenants, and the audit log keeps who, when and why (tenant.region.move, tenant.region.move.drained).

See where everything is

Terminal
oz0 region list
# REGION  EDGES        BACKENDS  PAYLOAD STORES        TENANTS        NODES
# eu      2 live of 2  default   sha256:3f1a0c9d2b11   default,nordic 6 (6 online)
# us      1 live of 1  default   sha256:9c2e44a01f73   yankee         2 (2 online)

A payload store shows as a digest, never its address. oz0 tenant backends names the regions whose edges report each backend, since one name is one Temporal service per region.

oz0 doctor adds a row per problem, each with its fix: a region with tenants and no live edge, edges of one region that write to different stores or report different backends, two regions that write to one store, nodes that joined in a region their tenant is not in, and a pinned tenant whose aliases have no target its region allows.

The console shows each node's region on the Nodes page, and cluster admins see the regions and move tenants under Fleet, Cluster, Regions. The recipient map of a pinned tenant has a row of kind region.

What stays central

Management is one per cluster. Whatever region a tenant is in, management keeps its records: the tenant, its people, roles and keys; plugins, versions, routines, settings and policies; secrets, sealed (only the tenant's region's edges ever open them, but any edge holding the cluster's master key could); the audit log; metering (calls, tokens, costs and job IDs); node records; the inventory; and plugin files edited in the studio.

Plugin artifacts are copied to every region's payload store, so each region's nodes download them there. So a region keeps a tenant's job data in place, not management's records about it. To keep those in a region as well, run that region as a cluster of its own.

When a region is down

A region whose edges, Temporal or payload store are down stops its tenants: their jobs wait where Temporal keeps them and go on when it is back, and their nodes reconnect only to the region's other edges. No other region takes over: it has none of the histories or payloads, and serving the tenant there would break the pin.

Run two or more edges per region (High availability), and for a Temporal that survives a cloud region's outage, use a Temporal Cloud namespace with multi-region replication as the region's backend. When management is down, every region keeps running from its edges' cached registry.

Copyright © 2026