Multi-region architecture
Why this matters
Single-region systems are simpler. When users are global, latency budgets eventually require regional distribution. When availability requirements are strict, you need failure isolation across regions. When regulations demand it, data must stay within geographic boundaries. Multi-region architecture is where senior engineers start; Staff engineers can design these systems from scratch, including the failure modes.
The non-obvious cost: multi-region adds operational complexity disproportionate to the problem it solves. A single-region 99.95% system is often more reliable than a multi-region 99.99% system, because the multi-region setup has more parts that can break in subtle ways. Reach for it when the requirements genuinely demand it.
The latency reality
Round-trip latencies between regions:
- Same DC: < 1ms
- Same region, different AZ: 1-2ms
- US East ↔ US West: ~70ms
- US East ↔ EU West (Ireland): ~80ms
- US East ↔ Asia (Tokyo/Singapore): ~150-200ms
- EU ↔ Asia: ~250ms
These numbers are physics — bound by speed of light through fibre. They don't get better with money. They shape every multi-region design decision.
Key implication: synchronous cross-region operations are slow. A synchronous write that requires acknowledgment from another region adds 70-200ms latency per write. If your service does N writes per request, multiply.
Replication topologies
Active-passive (single primary, replicas elsewhere)
One region holds the primary; other regions hold read-only replicas. Writes go to primary; reads can be served from any replica with acceptance of staleness.
Simplest model. Most managed databases support this out of the box. Failover requires promoting a replica in another region; RPO (recovery point objective) = replication lag, RTO (recovery time objective) = failover time.
Used by: most "multi-region" SaaS products that don't need active-active writes. AWS RDS, Aurora Global Database, Cloud SQL with read replicas.
Active-active (writes accepted in multiple regions)
Multiple regions accept writes locally. Replication is bidirectional. Conflict resolution kicks in when the same row is updated in different regions concurrently.
Two flavours:
- Sharded active-active: each region "owns" some partition of users (typically by user_id or geo). Writes for user X always go to user X's home region. No write conflicts. Easier model.
- True active-active: any region can write any record. Requires conflict resolution. Complex.
Sharded active-active is what most "multi-region SaaS" actually is. True active-active is for special cases (CRDTs, eventually-consistent collaboration tools, leaderless databases like Cassandra).
Quorum across regions (Spanner-style)
Strong consistency across regions via consensus protocol with members in multiple regions. Writes require quorum (e.g., 3 of 5 replicas across regions) to ack.
Cost: every write has cross-region latency baked in (you wait for at least one remote region). Writes are typically 100-200ms.
Benefit: real strong consistency. Reads from any region see the latest writes.
Used by: Spanner, CockroachDB, YugabyteDB. Expensive but correct.
Geo-DNS and traffic routing
How users find the right region. Three approaches:
- Latency-based routing: DNS returns the nearest region's IP. AWS Route 53 latency-based routing, Cloudflare anycast.
- Geo-based routing: DNS returns based on user's geographic IP. Useful for compliance (EU users to EU region).
- Anycast: same IP advertised from multiple regions; BGP picks nearest. Used by CDNs, DNS providers, sometimes by API services (Cloudflare Workers).
For active-passive: DNS routes all traffic to the active region; failover updates DNS (slow, due to caching) or uses a "VIP" that can flip between regions.
For sharded active-active: routing depends on user identity (after the user logs in, you know which shard / region owns them). The first request (anonymous) routes by latency or geo; the second request (authenticated) routes by user identity.
Data residency & compliance
GDPR (EU), CCPA (California), India's DPDP Act, China's PIPL, Russia's data localisation law — many jurisdictions require user data to stay within their borders. This forces multi-region.
Architectural implications:
- User → home region mapping based on jurisdiction, not just geography
- Data deletion / portability requests must be honored across all regions where data was stored
- Cross-border data transfer must comply with frameworks (EU-US Data Privacy Framework, Standard Contractual Clauses)
- Some data (logs, analytics) might be allowed to flow centrally; some (PII) must not
This often shapes the entire architecture. "Centralized analytics warehouse" might mean "send only aggregated, anonymised data; keep raw per-user data in-region."
Failure isolation
The whole point of multi-region: when one region fails, others survive.
The discipline: each region must be operationally independent. Shared dependencies kill the isolation.
- Each region runs its own copy of every service.
- Each region has its own DB primary (or its own writable replica in active-active).
- Each region has its own monitoring, logging, alerting (or at least can survive without central tools).
- Cross-region calls are async; never required for serving a user's basic flow.
- Deploys are staggered across regions; a bad deploy doesn't break everywhere simultaneously.
Common patterns
Read-local, write-home
Reads served from any region (closest to user). Writes route to the user's "home" region (where their data lives). Async replication keeps other regions reasonably fresh for reads.
Acceptable for: most SaaS apps where users mostly read their own data and occasionally write.
Active-active with idempotent writes
Any region accepts any write. Writes are idempotent (key-based) so duplicates from cross-region replication don't cause issues. Suitable for analytics ingestion, event logs.
Per-region tenant isolation
Each tenant is assigned a home region (decided at signup based on country / preference). All their data and processing happens in that region. Cross-region only for global features (analytics, billing aggregation).
Used by: most B2B SaaS. Simple to reason about. Aligns with compliance.
Failover
When a region fails, what happens?
Active-passive failover
- Detect: monitoring across regions reports active region is down.
- Decide: human operator (typically — automated failover is risky) confirms failover.
- Promote: replica in another region becomes new primary.
- Update routing: DNS / load balancer points traffic to new region.
- Wait: DNS caches take time to clear (TTL).
- Resume: traffic flows to new region.
Typical RTO: 5-30 minutes (largely DNS / human decision time).
Active-active failover
Traffic naturally fails over (other regions are already accepting writes). The "failover" is just removing the dead region from load balancer rotation. Seconds.
But: in-flight transactions in the dead region might be lost or duplicated. Reconciliation processes run when the region recovers.
Applied scenarios
Further reading
- AWS Builder's Library: Static stability using availability zones
- CockroachDB topology patterns — concrete multi-region patterns with tradeoffs.
- Spanner paper — globally consistent multi-region.
- AWS DR strategies — practical RTO/RPO patterns.
- Stripe: Building a multi-region active-active system (when published — Stripe writes about this in various posts on their blog).
- Figma database scaling — relevant for multi-region considerations.
- High Scalability example architectures