Multi-region replication is a database topology that copies data across geographic regions to cut read latency and survive outages. The enemy is physics: a round trip across an ocean costs tens of milliseconds before the database does any work, and chatty request patterns pay it repeatedly. Replication moves the data to the users — and immediately raises the questions that define this topic: who accepts writes, how stale may reads be, and whether you need any of it yet.
Key takeaways
| Question | Answer |
|---|---|
| The prize | Local reads everywhere; surviving a regional outage |
| The price | Replication lag, write latency to the primary, complexity |
| Default topology | One write primary + read replicas per region |
| The structural fact | Cross-region replication is asynchronous — lag is built in |
| First question | Is distance actually your latency problem? Measure before replicating |
Measure before you replicate
Before any topology decision, get the number it depends on — what a round trip actually costs your users per region:
// JavaScript / Node.js — Back4app JS SDK
// Latency probe: measure what users in this region actually feel
const probe = new Parse.Query('HealthCheck');
probe.limit(1);
const started = Date.now();
await probe.first(); // one lightweight read
const readMs = Date.now() - started;
const sample = new Parse.Object('LatencySample');
sample.set('clientRegion', 'eu'); // where this client runs
sample.set('readMs', readMs);
await sample.save(); // writes always travel to the primary
console.log(`read: ${readMs} ms — reads can be served locally,`);
console.log('writes pay the distance to the primary region'); // Flutter / Dart — Back4app Flutter SDK
// Latency probe: measure what users in this region actually feel
final probe = QueryBuilder<ParseObject>(ParseObject('HealthCheck'))
..setLimit(1);
final started = DateTime.now();
await probe.query(); // one lightweight read
final readMs = DateTime.now().difference(started).inMilliseconds;
final sample = ParseObject('LatencySample')
..set('clientRegion', 'eu') // where this client runs
..set('readMs', readMs);
await sample.save(); // writes always travel to the primary
print('read: $readMs ms — reads can be served locally,');
print('writes pay the distance to the primary region'); // iOS / Swift — Back4app Swift SDK
// Latency probe: measure what users in this region actually feel
let probe = HealthCheck.query().limit(1)
let started = Date()
probe.first { result in // one lightweight read
let readMs = Int(Date().timeIntervalSince(started) * 1000)
var sample = LatencySample()
sample.clientRegion = "eu" // where this client runs
sample.readMs = readMs
sample.save { _ in // writes always travel to the primary
print("read: \(readMs) ms — reads can be served locally,")
print("writes pay the distance to the primary region")
}
} // Android / Kotlin — Back4app Android SDK
// Latency probe: measure what users in this region actually feel
val probe = ParseQuery.getQuery<ParseObject>("HealthCheck")
probe.limit = 1
val started = System.currentTimeMillis()
probe.getFirstInBackground { _, e -> // one lightweight read
val readMs = System.currentTimeMillis() - started
val sample = ParseObject("LatencySample")
sample.put("clientRegion", "eu") // where this client runs
sample.put("readMs", readMs)
sample.saveInBackground { // writes travel to the primary
println("read: $readMs ms — reads can be served locally,")
println("writes pay the distance to the primary region")
}
} When the numbers do justify replicas, the machinery is standard — here as PostgreSQL logical replication, with lag as a first-class, queryable fact:
-- On the primary (region A): publish changes
CREATE PUBLICATION app_pub FOR ALL TABLES;
-- On the replica (region B): subscribe and stream
CREATE SUBSCRIPTION app_sub
CONNECTION 'host=primary.internal dbname=app'
PUBLICATION app_pub;
-- The number that defines your staleness window:
SELECT application_name,
now() - reply_time AS approx_lag
FROM pg_stat_replication;
One primary, many regions — the flow and the lag
This is the workhorse topology — replica sets in document databases, streaming replicas in relational ones — and its two costs are visible in the diagram. Write latency: every write travels to the primary region, so distant users pay the ocean crossing precisely on their mutating actions. Lag: cross-region streams are asynchronous — synchronous replication would add the full round trip to every commit — so replicas trail by milliseconds to seconds, and reads can be stale by that much. The classic bite is read-your-own-writes: save, refresh against the local replica, see nothing. Remedies are routing policy, not magic — send a user’s post-write reads to the primary, or pin their session until the replica catches up.
The step beyond — multiple write primaries — localizes writes too, but buys the CAP theorem’s hardest merchandise: concurrent conflicting writes in different regions must be detected and resolved. Conflict-free workloads (per-user data, append-only streams) wear it well; shared mutable state wears it badly.
Single-region vs. read replicas vs. multi-primary
| Dimension | Single region | Primary + regional replicas | Multi-primary |
|---|---|---|---|
| Read latency (global) | Distant for most | Local everywhere | Local everywhere |
| Write latency | Local to one region | Cross-region to primary | Local everywhere |
| Consistency | Simplest | Lag on replica reads | Conflict resolution required |
| Regional outage | Downtime | Failover to a replica | Keep serving |
| Complexity | Lowest | Moderate | Highest — respect it |
| Fits | Clustered users, early stage | Global readers, one write path | Global writers, mergeable data |
The honest reading of the table: each column to the right trades simplicity for locality. Most products should stand in the leftmost column that meets their latency and availability numbers — and many discover that a CDN for assets plus one well-chosen database region meets them already, since static weight usually dominates felt load time.
Common use cases
- Global read-heavy products. Catalogs, content, dashboards — browse-dominated traffic where regional replicas convert oceans into single-digit milliseconds.
- Regional user bases with global tails. Primary in the core market’s region, replicas where the tail lives.
- Disaster recovery and failover. A current copy in another region as the availability story — valuable even when latency never justified replicas.
- Data residency. Keeping specific tenants’ data in specific jurisdictions — tenant-aware partitioning by region, a policy cousin of replication.
- Portability insurance. Replicating on open-source engines keeps the topology yours — a quiet hedge against vendor lock-in that proprietary global databases do not offer.
Should you go multi-region? A decision matrix
| Multi-region earns its keep when… | Stay single-region when… |
|---|---|
| A distant user population measurably suffers | Users cluster in one geography |
| Read latency dominates and reads dwarf writes | The product is pre-launch or pre-traction |
| A regional outage is an existential risk | Slow queries, not distance, cause the latency |
| Contracts demand residency or regional DR | A CDN already fixed the felt slowness |
| You can staff the added operations | The team is still shipping core product |
The diagnostic order matters: profile queries and add indexes first, batch chatty request patterns second, put static assets on a CDN third, place your single region well fourth — and replicate fifth, when the remaining latency is genuinely geographic. Teams that skip to five inherit distributed-systems problems while their real bottleneck was an unindexed query.
Limitations and trade-offs
- Lag is structural. Asynchronous streams trail by design; every replica read carries a staleness window your product must tolerate or route around.
- Writes still cross the ocean. Single-primary topologies localize reads only — the checkout, the post, the booking still pay the distance.
- Failover is a procedure, not a promise. Promotion, cutover, and the risk of losing un-replicated writes (RPO again) — drill it before believing it.
- Multi-primary imports conflicts. Concurrent writes to the same record in two regions must merge somehow; “last write wins” is a data-loss policy wearing a default’s clothing.
- Cost scales with copies. Storage, egress between regions, and the engineering attention of one more distributed system — priced honestly, per region.
- Replication is not backup. Every replica faithfully copies your mistakes within seconds; point-in-time recovery exists for the failure class replication spreads.
Multi-region and latency on Back4app
Back4app is an open-source Backend-as-a-Service (BaaS) platform that combines a managed database, auto-generated REST and GraphQL APIs, authentication, file storage, and Cloud Code serverless functions. The replication mechanics live below your code: the managed database runs on replicated infrastructure with failover handled by the platform, and region choice at app creation puts the primary where your users are — the highest-leverage latency decision this article recommends making first. Because the stack is open source end to end, the topology stays portable: the same Parse Server and database engines run wherever you might later need a region the platform’s menu does not list.
Frequently asked questions
What is multi-region database replication?
Running copies of one database in different geographic regions and streaming changes between them. In the common topology, a primary in one region accepts all writes while replicas elsewhere serve reads to nearby users. The goals are lower read latency — data physically closer to users — and survival of a whole region going dark, at the price of replication lag and operational complexity.
Why does distance add latency to database queries?
Physics before software: signals cross oceans in tens of milliseconds each way, and a transatlantic round trip costs on the order of 70–100 ms before any database work happens. A chatty request that makes five sequential queries pays that toll five times. Replication attacks the problem by moving data near users; the alternative is fewer, batched round trips.
What is replication lag?
The delay between a write committing on the primary and appearing on a replica — typically well under a second within a region, more variable across regions and under load. Lag is why a user can create a record, refresh against a local replica, and not see it. Cross-region replication is asynchronous in practice, so some lag is structural, not a bug to fix.
What is read-locality vs. write-latency?
The core trade of the single-primary topology. Replicas make reads local everywhere — a win for browse-heavy products. Writes still travel to the primary region, so distant users pay cross-region latency exactly on the actions that change data. Multi-primary topologies localize writes too, but import conflict resolution: two regions can now change the same record concurrently.
Do reads from replicas return stale data?
They can, by lag's worth. Most reads tolerate it — feeds, catalogs, dashboards. The classic failure is read-your-own-writes: a user saves, then reads from a replica that has not caught up, and their change seems lost. Standard remedies: route the reads that follow a user's writes to the primary, pin sessions briefly after writing, or require replicas caught up past the user's last write.
Is multi-region the same as a CDN?
Same instinct — move things near users — different layer and difficulty. A CDN replicates immutable static assets, where copies cannot conflict and staleness is managed by cache expiry. Database replication moves mutable state, importing consistency, lag, and conflict questions a CDN never faces. Many products get most of the felt speedup from a CDN plus one well-placed database region.
When is multi-region overkill?
When users cluster in one geography, when the product is pre-launch, or when latency complaints trace to slow queries and chatty APIs rather than distance. A well-indexed single-region database behind a CDN serves a remarkable share of successful products. Multi-region earns its complexity when a distant user population is measurably paying — and choosing the right single region comes first.
Does a managed backend handle replication for me?
The mechanics, yes: managed databases replicate for durability and failover as a matter of course, and platform tiers place infrastructure across regions. What remains yours is the geography: knowing where your users are, choosing where data should live, and deciding whether distant reads justify replicas. The platform runs the topology; the product decides it.