Run an app across regions by deploying the same stateless services from one definition to every region, putting a health-checked global routing layer in front that sends each user to the nearest healthy region, and choosing a data topology per database (single primary with replicas, multi-primary, or distributed SQL) based on how much write latency and data loss you can accept. Failover for stateless services is a routing change, while failover for databases is a promotion that must be designed and tested. Control Plane runs one workload definition active-active in every location of Control Plane’s Global Virtual Cloud (GVC) behind a global endpoint that routes to the nearest healthy location, and its template catalog includes multi-location PostgreSQL, multi-master PostgreSQL, Redis, and CockroachDB.
Disclosure: Control Plane publishes this guide.
TL;DR
- One definition everywhere. Deploy the same workload definition to every region so regions cannot drift apart.
- Global routing with health checks. DNS routing, anycast load balancers, or both send users to the nearest healthy region and away from failures.
- A data topology per service. Single primary with replicas, multi-primary, or distributed SQL, each with its own trade-off between write latency, data loss on failover, and complexity.
- Failover differs by layer. Stateless services fail over through routing. Databases need fencing, promotion, and repointed connections, automated and rehearsed.
- Quorum sets the location count. Automatic failover needs a majority, so two locations survive no location loss, three survive one, and five survive two.
- On Control Plane, one definition runs active-active in every location of a GVC behind a global endpoint, with database templates for the data layer.
How do I run my app across multiple regions?
The goal is to deploy the same application to every region without hand-built per-region setup, so adding or removing a region is an operational change.
How do I deploy one application to multiple regions with a single configuration?
- Make services stateless. Move sessions, caches, and mutable state into external stores so any instance can be replaced or moved.
- Externalize configuration and secrets. Connection strings, keys, and feature flags come from a secrets manager or configuration service, so one container image runs in any region.
- Use infrastructure as code or a platform with multi-region placement. Terraform or Pulumi can target many regions from one module, and some platforms place a workload in several regions from a single definition.
- Override per region only where you must. Limit overrides to region-specific needs such as instance types or data residency labels; keep the image, resources, and health checks identical.
- Choose a rollout order. Region-by-region rollouts catch problems before they spread; all-at-once rollouts are faster but risk a bad release hitting every region together.
- Check regional dependencies first. Quotas, instance availability, and data residency rules differ by region, so request capacity before you need it.
For one application on AWS, GCP, and Azure at once, see running the same app across AWS, GCP, and Azure.
How do I route users to the nearest healthy region automatically?
Two routing mechanisms, both driven by health checks, cover most designs.
- DNS latency and geo routing. Amazon Route 53 offers latency, geolocation, and failover routing with health checks. Azure Traffic Manager routes at the DNS level with endpoint monitoring. Google Cloud DNS routing policies support geolocation, weighted round robin, and failover policies with health checks. DNS routing is simple, but TTLs and client caching slow the switch.
- Anycast global load balancers. Google Cloud’s global external Application Load Balancer uses anycast IPs for HTTP(S) traffic. AWS Global Accelerator gives static anycast IPs that route TCP and UDP to the nearest healthy endpoint. Azure Front Door combines global routing with WAF and caching. These route each connection without waiting for DNS caches to expire.
- Health checks. Check application health endpoints in addition to TCP ports, and require several failures before removing a region so traffic does not flap.
| Mechanism | Failover speed | Granularity | Caveats |
|---|---|---|---|
| DNS latency or geo routing | Depends on TTLs and client caching | Per DNS lookup | Some resolvers and clients hold records past the TTL |
| Anycast global load balancer | Faster, independent of DNS caching | Per connection or request | Protocol support varies by service |
| DNS plus anycast | Fast for new connections; open connections may need retries | Per connection | More moving parts |
How do I run stateful workloads like databases across multiple regions?
Every multi-region database design trades write latency, data loss on failure, consistency, and operational effort against each other.
Replication modes
- Synchronous replication makes the primary wait for at least one remote replica to confirm each write. Committed data survives a failover to that replica, but every write pays a cross-region round trip, which grows with distance. Writes stall if no synchronous replica is reachable, so fail over only to a replica confirmed in sync.
- Asynchronous replication confirms writes locally and ships changes in the background. Writes stay fast, but anything not yet replicated when the primary fails is lost, so the data at risk equals the replication lag at that moment.
Database topologies
- Single primary with read replicas. One region takes writes; others serve reads and can promote a replica. Amazon Aurora Global Database works this way, and PostgreSQL with Patroni provides the same pattern in open source with automatic leader election.
- Multi-primary (active-active writes). Every region accepts writes, which removes the write-latency penalty for remote users but requires conflict resolution. Last-writer-wins is simple and can silently discard concurrent updates; ownership rules or conflict-free data types reduce that risk. Azure Cosmos DB supports multi-region writes.
- Distributed SQL with consensus. Each write commits once a majority of replicas agree, giving strong consistency without a single primary at the cost of cross-region write latency. Google Cloud Spanner, CockroachDB, and YugabyteDB take this approach.
- Partitioning by tenant or region. Each tenant or partition has a home region that takes its writes, which avoids conflicts and helps with data residency.
| Topology | Write latency | Data loss on regional failover | Consistency | Operational effort | Fits |
|---|---|---|---|---|---|
| Single primary, async replicas | Low in the primary region | Recent writes can be lost | Strong in the primary region | Low to moderate | Most applications |
| Multi-primary | Low everywhere | Unreplicated writes in the failed region are lost or delayed until it recovers | Eventual or causal | High | Global write-heavy apps that tolerate conflicts |
| Distributed SQL (quorum) | Higher (cross-region round trip) | Committed writes survive while a quorum remains | Strong | Moderate to high | Strong consistency across regions |
| Partitioned by tenant or region | Low within a partition | A partition’s recent writes can be lost if its home region fails | Strong within a partition | Moderate | Multi-tenant SaaS, data residency |
Quorum math and location count
Consensus systems need a majority to agree, so a cluster across N locations survives the loss of floor((N-1)/2) locations.
- Two locations survive no location loss for automatic failover, because the survivor cannot form a majority alone.
- Three locations survive the loss of one, the minimum for safe automatic promotion.
- Five locations survive the loss of two.
With two locations and no witness, a system cannot tell a network partition from a failure, so automatic promotion risks split brain. Run consensus-based databases in at least three locations, or add a witness or arbiter in an independent third location.
Caches, queues, and object storage
- Caches. Redis replication with Sentinel or Redis Cluster spans regions, and Sentinel needs a majority across three locations to fail over automatically. Redis replication is asynchronous, so treat caches as rebuildable, and expect a cold cache in the surviving region to shift load onto the database.
- Queues and streams. RabbitMQ supports federation and shovels between clusters, and Kafka uses MirrorMaker 2 for cross-cluster replication, which translates consumer offsets approximately, so consumers must tolerate duplicates. Most designs keep ordering per partition within a region and accept eventual consistency across regions.
- Object storage. S3 Cross-Region Replication, Cloud Storage dual-region and multi-region buckets, and Azure geo-redundant storage replicate asynchronously, so the newest objects may be missing or unreadable in the surviving region right after a failure. Cloud Storage’s default replication targets a 12-hour RPO, and turbo replication on dual-region buckets targets 15 minutes.
Consistency pitfalls
- Read-your-writes. Users moved to another region, or reading from asynchronous replicas, can see stale data; route reads to the primary right after a write, or use session tokens.
- Unique IDs. Multi-primary designs need globally unique IDs, such as UUIDv7, instead of per-node sequences.
- Schema changes. Use expand-and-contract migrations, because old and new code run side by side during region-by-region rollouts, and check whether your replication carries DDL.
How do I fail over a database-backed application between cloud regions?
Run database failover as an ordered sequence.
- Detect. Application-level health checks confirm the primary region is down rather than slow.
- Fence the old primary. It must lose its leader lease and demote itself; use STONITH or a fencing token where available, and revoke its write credentials if it is still reachable, so two primaries never write at once.
- Promote. Promote a replica in a surviving region. With asynchronous replication, writes not yet replicated are lost, so track replication lag continuously to know your real RPO.
- Repoint applications. A stable endpoint or proxy that follows the current leader makes this automatic; otherwise applications need new connection strings or DNS changes. Drain or kill pooled connections to the old primary.
- Verify. Confirm writes succeed, replicas stream from the new primary, and application health checks pass.
- Rebuild the old region as a replica. Export any writes it holds that never replicated, resync it with pg_rewind or a fresh base backup, and only then let it rejoin as a replica. Moving the primary back is a separate, planned operation.
Clients should retry with idempotency keys, because in-flight transactions may have committed just before the failure.
Alert when replication lag exceeds your RPO, because lag grows under heavy writes and network trouble. Serving reads while blocking writes is a useful degraded mode when promotion is unsafe. Rehearse the whole sequence in regular game days to measure real RTO and expose hidden dependencies; for testing approaches and costs, see active-active vs. active-passive costs.
How can my company avoid being taken down by the next major cloud outage?
Each item removes a common cause of regional downtime.
- Run in more than one region, or on more than one provider; availability zones alone share a region’s fate.
- Audit hidden single-region dependencies: DNS, secrets, container registries, CI/CD, monitoring, and identity.
- Choose a data topology per service instead of one pattern for everything.
- Test failover regularly in production-like conditions and fix what breaks.
- Keep one runbook for drills and real events, and update it after each drill.
- Keep enough headroom or reserved capacity for surviving regions to absorb a failed region’s load; autoscaling can hit quota or capacity limits during a regional outage.
- Plan who is paged, what the status page says, and how customers hear about it.
For a step-by-step regional plan, see keeping your app online during an AWS region outage, and for incident history, the cloud outage tracker.
How Control Plane fits
Control Plane is the platform for running unbreakable apps and agents. It combines any cloud, neocloud, and bare metal into a GVC, the set of locations a workload runs across, and runs serverless, standard, stateful, and cron workloads on AWS, GCP, and Azure, on Kubernetes clusters you already run, and on your own machines turned into managed locations, including on premises.
One definition, every location. Each location of a GVC serves traffic at once, and the global endpoint sends each request to the nearest healthy one. Disabling a location removes its replicas and routes traffic to the locations that remain. Location routing options include latency offsets that make a location appear closer or farther, and priority routing tiers, where a lower-priority tier receives traffic only when every location in the higher-priority tier is unavailable. Domain route changes apply to every location of a GVC at once. Workload updates roll out behind readiness checks, each location keeps serving the last healthy version until the new one reports ready, and rolling back is an explicit action.
Database templates. Postgres Multi-Location deploys one PostgreSQL cluster managed by Patroni whose members span several locations, with a single primary that takes all writes, asynchronous streaming replicas in the other locations, automatic promotion of a replica in a surviving location when the primary’s location is lost, and an HAProxy tier in every location that routes connections to the current leader, so applications connect to a stable name in their own region. Automatic promotion needs a quorum, so plan for at least three locations. Because replication is asynchronous, the most recent writes can be lost when a location fails. pgEdge deploys active-active PostgreSQL with Spock multi-master replication across the locations you list, with a per-location HAProxy failover tier and PgBouncer pooler. Redis multi-location runs one Sentinel per location, so two locations give no automatic failover and three survive the loss of one; etcd multi-location tolerates one loss with three locations and two with five. A CockroachDB template is also available. Template backups are optional and off by default, restore support varies by template (pgEdge’s backup job also restores, while others document manual procedures), and Control Plane does not make arbitrary databases multi-region automatically.
Proof. During the October 20, 2025 AWS us-east-1 outage, which lasted about 15 hours, Control Plane customers with us-east-1 in their GVC had no downtime, and their workloads were “active and running in healthy locations within 10 seconds,” according to Control Plane internal incident telemetry (details).
The 99.999% availability SLA applies to workloads running at least two replicas in at least two locations. Those locations can be two regions of one cloud or locations on different providers. The SLA covers workloads; database failover follows the quorum rules above. Control Plane handles Day 2 operations for you, including autoscaling, Capacity AI right-sizing, built-in observability, and security, with no Kubernetes cluster you have to operate, and it ships Terraform and Pulumi providers. Customers typically cut compute costs 30 to 50 percent compared with running directly on AWS, GCP, or Azure. Control Plane is PCI DSS Level 1, SOC 2 Type II, HIPAA, and GDPR compliant.
FAQ
Short answers to common multi-region questions.
How do I run my app across multiple regions?
Deploy stateless services from one definition to every region, put health-checked global routing in front, and pick a replication topology for each database based on its write-latency and data-loss tolerance.
How do I deploy one application to multiple regions with a single configuration?
Make services stateless, externalize configuration and secrets, and use infrastructure as code or a platform with multi-region placement, keeping per-region overrides to the minimum.
How do I route users to the nearest healthy region automatically?
Use DNS latency or geo routing with health checks, an anycast global load balancer, or both. Anycast avoids waiting on DNS caches; DNS is simpler to adopt.
How do I run stateful workloads like databases across multiple regions?
Choose single primary with replicas, multi-primary with conflict handling, distributed SQL with quorum writes, or partitioning by tenant or region, and run consensus-based systems in at least three locations, or two plus a witness in a third.
How do I fail over a database-backed application between cloud regions?
Detect the failure, fence the old primary, promote a replica in a surviving region, repoint applications through a stable endpoint, verify, and rebuild the failed region as a replica.
What happens to writes during a failover with asynchronous replication?
Writes committed on the old primary but not yet replicated are lost; the amount equals the replication lag at the moment of failure.
Why do I need three locations for automatic database failover?
Automatic failover needs a majority. With two locations the survivor cannot form one, while three locations let the remaining two elect a new primary.
What is the difference between active-active and active-passive?
Active-active serves traffic from every region at once, though writes may still go to one primary; active-passive sends all traffic to one region and switches only on failure.
How can my company avoid being taken down by the next major cloud outage?
Run in more than one region or provider, remove single-region dependencies, choose data topologies per service, and rehearse failover until it is routine.
Can Control Plane run my database across multiple regions?
Yes, through templates: Postgres Multi-Location (single primary with automatic promotion), pgEdge (multi-master PostgreSQL), Redis with Sentinel, etcd, and CockroachDB, each spanning the GVC locations you choose.
Talk to the Control Plane team or sign up free to run one definition across every region you need.
Originally published on the Control Plane blog.