Cross-Cluster Replication
This page is part of the documentation for Orleans.Lattice 9.9.0 (release line 9.9), built 2026-10-04. It is also published as markdown, with every table and list, at README.md, and llms.txt lists every page.What it shows
Active-active cross-cluster replication. This sample stands up two independent
in-process Orleans clusters (site-a and site-b), wires them together with
Orleans.Lattice replication over the canonical gRPC push transport, then writes a
key on site-a only and watches it converge onto site-b - with no direct
write to site-b. The orders tree is opted into replication as a
last-writer-wins register; each site ships its mutations to the other.
Like the CrossClusterAuthorization sample, it hosts both clusters in one process, each on its own ASP.NET Core / Kestrel pipeline, because the gRPC replication receiver is served over HTTP/2 (here plaintext h2c on loopback).
Run it
dotnet run --project samples/CrossClusterReplication
Expected output
Starting two independent Orleans clusters (site-a, site-b)...
Both clusters ready and peered over gRPC.
== Before ==
site-b sees 'order/1001' = (absent)
== Writing on site-a only ==
site-a wrote 'order/1001' = CONFIRMED
== Waiting for convergence on site-b (no direct write) ==
. converged.
site-b now sees 'order/1001' = CONFIRMED
[OK] the write made on site-a converged onto site-b across clusters.
(The number of . poll dots before convergence varies run to run with shipping
latency; the before/after values and the converged result are stable.)
When to use
- Multi-region / multi-datacenter deployments that want each region to serve reads and writes locally while staying eventually consistent with the others.
- Active-active topologies where any cluster may write any replicated tree and conflicting updates must converge deterministically by CRDT merge mode.
When not to use
- Single-cluster deployments - replication adds a shipping pipeline you do not
need. Use plain
AddLatticethere. - Strong/linearizable cross-region consistency. Replication is convergent and causally consistent, not a global consensus protocol.
Notes on this sample
- Uses plaintext HTTP/2 (h2c) on loopback with
AllowPlaintextEndpoints = true. Each site binds Kestrel to HTTP/2 with no certificate and grpc-dotnet speaks h2c by prior knowledge over anhttp://address, so no process-wide switch is involved. Production deployments should usehttps://peer endpoints and leaveAllowPlaintextEndpointsat its secure default. - Receiver-side shared-secret authentication is turned off
(
RequireAuthentication = false) because this is a loopback demo with no secret material. Production must supply a secret and leave authentication on. - The gRPC ports default to
17001/17002, and the two clusters also bind Orleans silo ports11111/11112and gateway ports30000/30001; change them inProgram.csif those are taken on your machine.