Master multi-region database architecture using global transaction sequencing. Learn to eliminate split-brain issues in active-active setups. Read now.
Why Active-Active Needs a Shared Clock of Truth
An active-active database runs writable replicas in more than one region so users can write near them and keep serving traffic if a region fails. The hard part is not replication itself. It is agreeing on a single order of writes when two regions accept changes at the same time. Without a global sequence, the same key can diverge: each side believes its version is newest, and you get split-brain—two valid histories that cannot be merged without data loss or manual repair.
Global transaction sequencing solves that by assigning every committed write a total order that all regions honor. Local latency stays low because writes can still land near the client, but the system treats the sequence number—not wall-clock time alone—as the authority for conflict resolution and catch-up.
How Global Transaction Sequencing Works
At a high level, each transaction receives a monotonically increasing sequence token before or at commit. Regions exchange those tokens with the payload so a replica can apply remote changes in the same order as the origin. When two writes touch the same data, the higher sequence wins, or the engine applies a defined merge rule that still respects the global order. Readers that need a consistent view wait until their local replica has applied all sequences up to a chosen watermark.
You do not need perfect clock sync across continents for this model to work. Sequence tokens can come from a coordinated sequencer, a hybrid logical clock, or a consensus group that only orders commits—not every row. The design choice is where that ordering service lives and how much latency you accept on the write path versus how much conflict you push to application-level resolution.
- Central sequencer: Simple total order; can become a cross-region bottleneck if every write waits on it.
- Partitioned sequencers: Order per shard or key range; scales better, but cross-partition transactions need extra rules.
- Hybrid logical clocks: Combine physical time with a logical counter so causal order is preserved even when clocks skew.
Eliminating Split-Brain in Practice
Split-brain appears when two active regions accept conflicting writes and later cannot decide which history is correct. Global sequencing closes that gap by making “correct” mean “later in the shared sequence,” not “the replica that answered first.” After a network partition heals, lagging regions replay missing sequence ranges until they catch up. Divergent branches are not both kept as equals; one is ordered ahead of the other by design.
Operationally, protect the sequencing path as carefully as the data path. Monitor sequence lag per region, reject or queue writes if the local sequencer cannot advance, and define clear behavior when a region is isolated: either it becomes read-only, or it continues writing into a temporary branch that must reconcile under the same global rules when connectivity returns. Ambiguous dual-primary modes without sequencing are what recreate split-brain.
Design Tradeoffs and Practical Guidance
Global ordering buys a single timeline at the cost of coordination. Writes that require a fresh sequence token may wait on a remote hop; designs that batch tokens or sequence only at commit reduce that tax. Favor key designs that keep related rows in the same ordering domain so most transactions stay single-partition. Expose sequence or watermark metadata to the application when you need causal reads (“read your writes” across regions) instead of hoping eventual consistency is enough.
Test failure modes on purpose: region isolation, delayed replication, and simultaneous updates to the same key. Confirm that recovery never produces two live primaries with incompatible histories. If your product can tolerate last-writer-wins on a few fields but needs strict order on money or inventory, apply global sequencing only where correctness demands it—and document that boundary so the rest of the system does not assume stronger guarantees than you provide.