Skip to content

CONCEPT Cited by 1 source

Regional read replica

Definition

A regional read replica is a full, read-only copy of a primary database's dataset, placed in a geographic region distinct from the primary region, reachable by applications deployed in or near that region at in-region network latency (typically single-digit milliseconds) rather than the cross-region latency they would pay dialing the primary (tens to hundreds of milliseconds).

The shape is strictly more specific than "a read replica":

  • Read replica (generic): any replica that serves reads; frequently co-located with the primary in the same region / availability zone.
  • Regional read replica (this concept): a read replica whose defining purpose is to sit near a non-primary-region application tier, cutting the per-query network RTT from cross-region to in-region.

Canonical motivating number

"For an application deployed to Frankfurt, talking to a Northern Virginia database can add nearly an extra ~90ms PER query. By adding a read-only region in Frankfurt, we can reduce that to ~3ms per query. (Data based on select * from books limit 10.)" (Source: sources/2026-04-21-planetscale-introducing-planetscale-portals-read-only-regions.)

~90 ms → ~3 ms per query is the canonical 30× delta. For a page that fires N sequential queries, latency savings multiply by N — this is why the effect is outsized for ORMs that do per-association fetches (the Rails N+1 / preloading shape) and for request paths that make 3–10 DB round-trips before rendering.

Compare the broader framing on edge-to-origin database latency: regional read replicas are one of the two canonical remedies (the other being caching proxies like systems/hyperdrive; a third, CDN-style caching, applies only for cache-friendly reads).

The architectural shape

  • One writing region (primary). Writes are routed there, period. Regional read replicas are eventually consistent copies; they do not accept writes.
  • N read-only regions (replicas). Populated by asynchronous replication from the primary — typically MySQL binlog-based / Vitess VReplication for the PlanetScale flavor; physical streaming replication for Postgres; engine-specific for each vendor.
  • Each replica region exposes a MySQL / Postgres endpoint the application dials. The application's job: pick which endpoint to dial for reads, based on where the application pod is deployed.

This yields a read-write-split shape, generalized across regions:

write     → primary-region endpoint (one of these, globally)
read (us) → us-region replica endpoint
read (eu) → eu-region replica endpoint
read (ap) → ap-region replica endpoint

The routing layer can be application-level (per-region env var + per-region connection string, the 2022-era PlanetScale Portals shape — see patterns/per-region-read-replica-routing) or network-level (single global credential + anycast-ish latency-DNS + warm mesh connections, the 2024-era Global Network shape).

Structural costs

  • Storage scales linearly with region count. "if your production branch is 10GB, each read-only region added will increase your total storage cost by 10GB." Each regional replica is a full dataset copy. No logical-slicing optimization.
  • Write-path latency unchanged. Writes still pay the user → primary-region RTT. If the app is in Frankfurt and the primary is in NoVa, every write eats ~90 ms of network before any DB work. Regional read replicas fix the read half of a bimodal latency profile, not the write half.
  • Replication lag now has geographic component. Cross-region replication lag is wider-tailed than same-region (bigger bandwidth-delay product, more queueing, more potential for network weather). Any RYW mechanism that relies on a lag bound (e.g. the 2-second session-cookie window from patterns/session-cookie-for-read-your-writes) must pick a bound that covers the cross-region tail, not just the same-region tail.
  • Read-your-writes is now a cross-region problem. A user's write commits in region A; their next read arrives in region B whose replica hasn't seen the write yet. Fix requires either reading-from-primary for a window (session cookie), waiting for a replication signal (LSN / GTID comparison), or accepting stale data (the silent default).

When this is wrong

  • Write-heavy workloads. If writes dominate, regional read replicas don't help — writes still fly cross-region. Multi-primary is the wrong answer too (MySQL has no good multi-master story; it's sharding + geographic shard-placement, a much harder architecture).
  • Read-your-writes-critical flows with low tolerance for session pinning. If the session-cookie trick is a UX dealbreaker, the choice is either "always read from primary" (kills the point) or a token-based scheme (plumbing through every read site).
  • Cache-friendly reads. If the workload is a power-law URL distribution with high cache hit rate, a CDN cache in front of a centralized DB is often cheaper and hits the same latency goal — no replication to manage, no storage duplication. Regional replicas win when cache hit rate is low (personalized data, user-specific queries).

Comparable productised forms

  • PlanetScale Portals — the canonical MySQL-side productisation.
  • PlanetScale Global Network — evolution of Portals' connection model, adds CDN-shaped edge.
  • AWS Aurora Global Database — AWS's version: one primary region, up to 5 secondary read-only regions, cross-region physical replication via AWS's internal network.
  • MongoDB Atlas "global clusters" (a different thing — uses zone sharding to geo-partition writes, not just reads).
  • Vanilla self-managed MySQL binlog replication to a distant replica — the shape has been possible for decades; the productised versions just automate the operational half.

Seen in

Last updated · 378 distilled / 1,213 read