Multi-Region and Geo-Distributed Systems Questions
Running a system across regions and continents: multi-region replication, data residency and sovereignty, geo-routing and CDN edge distribution, cross-region consistency and quorum placement, and conflict resolution when two regions accept writes. Covers regional failover and split-brain prevention, recovery objectives (RTO/RPO), region-by-region rollout and blast-radius containment, and the latency, cost, and consistency tradeoffs of going global. Global distribution strategy across the service and data tiers.
Design a multi-region replication and failover strategy meeting regulatory PII residency (e.g., EU-only). Address replication scope (what data is replicated), selective replication, failover constraints (no fallback that violates residency), routing, testing, and audit logging to prove compliance during incidents.
Sample Answer
Direct answer
The constraint that changes everything here is that failover targets are limited to regions inside the same jurisdiction, so this needs its own failover pairing and its own tested runbook, separate from any global failover strategy the rest of the system uses.
Framework
- Replication scope: decide, field by field, what's actually personally identifiable information (PII) and therefore residency-bound, versus operational metadata that can replicate more broadly, for example anonymized error rates. Only the PII-bearing tables need the strict pairing.
- Selective replication: replicate PII only between the approved in-jurisdiction region
pair, and replicate non-PII operational signals, aggregate metrics, not row-level data, more
broadly for global observability. Decide synchronous versus asynchronous for that pair
explicitly, because that single choice sets the recovery point objective before anything else
does. Synchronous replication holds the commit until the second approved region has the write,
so committed data loss is effectively zero, but every write then pays the round trip between
the pair: if the two approved regions sit 20ms apart, that 20ms lands on every write, forever.
Asynchronous replication keeps writes fast and accepts a small, bounded loss window equal to
the replication lag. Pick one and state the number it implies. A design that claims synchronous
replication and a multi-second data-loss budget in the same breath has not actually made the
choice, and that inconsistency is the kind of thing an auditor reads as a control nobody
understands. - Failover constraints: the failover automation must have a hard rule that a PII-bearing service's failover target list contains only approved in-jurisdiction regions, enforced in the failover controller's configuration, not just documented as a policy someone has to remember.
- Routing: use anycast, a networking technique where the same IP address is advertised from multiple locations and traffic routes to whichever is nearest, or geo-DNS at the edge to route users to their correct jurisdiction's entry point, then a strictly in-jurisdiction failover behind that entry point if the primary region degrades.
- Testing: run failover drills specifically for the residency-constrained pair on a regular cadence, for example quarterly, because this pairing is exercised far less often than the main system's failover and is more likely to have silently rotted.
- Audit logging: every failover event for PII-bearing services writes an immutable log entry recording which region became primary, when, and confirmation the new primary is within the approved jurisdiction, so it can be handed to a regulator as evidence data never left its approved boundary during the incident.
Worked example
One EU region is primary and a second EU region is the sole approved failover target for the customer-PII service. Because both regions are approved, the team replicates asynchronously between them, a
deliberate choice to keep the cross-region round trip off the write path in exchange for a
small, stated loss window. A quarterly drill confirms failover completes within a 10-minute
recovery time objective (RTO, the maximum acceptable time to restore service) and that measured
data loss stays under the 5-second recovery point objective (RPO, the maximum acceptable amount
of data loss, measured in time) that choice implies, and the audit log for the drill, and for any real incident, records both regions' jurisdiction membership as part of the compliance evidence trail.
Trade-offs and pitfalls
Reusing the same failover automation and configuration for PII and non-PII services is the most common way this breaks, since a well-intentioned "add another healthy region to the pool" change for the general system can silently add a non-approved region to the PII service's pool if they share config. Under-testing this pairing because it "basically never triggers" is how you discover it's broken during the one incident that needed it.
Design a globally distributed user profile service that must serve 500M users, prioritize low-read-latency (p95 < 50ms), and allow eventual consistency across regions. Include choices for data replication, read/write routing, conflict resolution (CRDTs vs last-write-wins), caching layers, and how to handle GDPR-style data deletion requests across regions.
Sample Answer
At 500 million users with a sub-50ms read target, the design's center of gravity is "read locally, write to a home region, replicate asynchronously," with conflict resolution split by field type (automatic merging where that's safe, deterministic last-write-wins where it isn't) and a deletion workflow that treats a GDPR-style (GDPR: the EU's General Data Protection Regulation, which gives users a legal right to have their personal data deleted) erasure request as a high-priority event every region must acknowledge, not an ordinary asynchronous update.
Data replication and read/write routing
A profile service like this is typically read-dominated, for example around 90 percent reads and 10 percent writes per user on a typical day, which is why the design below spends its complexity budget on making reads fast and cheap everywhere rather than on optimizing the comparatively rare write path. Each user is assigned a deterministic home region, and the assignment function matters more than it looks. Hashing the user id is deterministic and trivially rebalanced, but it throws away the one input that actually determines write latency and legal exposure, namely where the user is; a European user hashed into an Asia-Pacific home region pays a trans-continental round trip on every profile edit and stores personal data in a jurisdiction nobody chose. Assign the home region from the user's own locality at signup (with an explicit, auditable residency override where regulation requires one) and keep a hash only as the tie-breaker for users with no locality signal, so the mapping stays deterministic without being arbitrary. Whatever the function, once assigned it is recorded rather than recomputed, so a user who travels does not silently change home regions; writes go to the home region first, then replicate asynchronously to every other region via a change-log stream. Reads are always served from the requester's local region, backed by a local cache, which is what keeps the p95 (95th percentile: 95 percent of requests are faster than this number) under 50ms regardless of where the user's home region is, at the cost of a read from a non-home region potentially being a few seconds stale relative to a very recent write.
Conflict resolution: CRDTs versus last-write-wins
For fields where merging concurrent updates makes sense (a list of interests, notification preferences), use a CRDT (conflict-free replicated data type: a structure designed so concurrent updates made in different regions merge automatically into the same result without needing a coordinator), for example an add-wins set, so two regions adding different preferences at the same time both survive the merge. For single-value fields where merging doesn't make sense (a legal name, a primary email), use LWW (last-write-wins: a rule that keeps whichever update carries the latest timestamp and discards the other), tagged with a timestamp that accounts for clock differences across regions, accepting that the earlier of two truly concurrent edits is silently lost, the correct behavior for fields where keeping both isn't meaningful.
Caching
A regional in-memory cache serves most reads with a short TTL and stale-while-revalidate (serving the cached value immediately while refreshing it in the background), which is what makes the sub-50ms p95 achievable at billions of reads per day.
GDPR-style deletion across regions
Treat a deletion request as a high-priority event, not a normal write, and separate the three things that are usually collapsed into one, because collapsing them is what leaves data being served while everyone believes it is gone.
1. Suppress reads everywhere, immediately, on a channel that cannot be stuck behind replication. Publish the user identifier to a small, independently replicated suppression set that every region's read path consults before returning a profile, and invalidate that key in every regional cache in the same step. This has to bypass the ordinary change-log stream entirely, because the whole point is that the stream can be backlogged. It also has to bypass stale-while-revalidate: a suppressed key must be a hard miss that returns not-found, never a stale copy served while a refresh runs, since stale-while-revalidate is explicit permission to keep serving an expired value and that is exactly the wrong behaviour here.
2. Then run the acknowledgement protocol. Mark the record deleted in its home region, propagate the tombstone to every region ahead of ordinary replication traffic, and require an explicit acknowledgment from every region before the request is considered fulfilled. This step is what gives you PROOF, and proof is genuinely valuable, but be clear that it is an observability guarantee and not the thing that stops the data being served; step 1 is what stops the data being served.
3. Then purge. Only after every region confirms does a background job perform the actual permanent purge from storage, caches, and backups, while an audit log retains proof that the deletion happened, without retaining the deleted personal data itself, for compliance purposes.
Give the protocol a deadline as well as an acknowledgement requirement. A region that has not acknowledged within the internal target (minutes, not hours) is an incident with an owner, not a row on a dashboard, because the regulatory clock for responding to an erasure request runs in days and weeks while the backlog is measured in minutes; a design that can wait indefinitely for one region has no bound at all.
Worked example
A user in Europe requests deletion. The home region marks the record deleted and pushes a tombstone event to the other regions' replication streams within a few seconds under normal conditions. If a region has a backlog and takes 40 minutes to acknowledge, the deletion is not yet considered complete system-wide. Be precise about what that buys and what it does not. Waiting for every region to acknowledge is what makes the gap VISIBLE, and visibility is worth having, because a design that fired the delete and assumed success would have silently left personal data live in the backlogged region well past when compliance believed it was gone. What the acknowledgement protocol does NOT do on its own is stop the data being served: for those 40 minutes the backlogged region still answers reads with the profile, and if the purge is gated on full acknowledgement then even the regions that already acknowledged are still holding the value in cache. That is why the read-suppression step runs first and independently. With suppression in place the 40 minutes become a compliance-reporting problem (the purge has not finished, and someone is paged), rather than 40 minutes of a deleted user's personal data being returned to callers in every region.
Trade-offs and pitfalls
Asynchronous replication keeps reads fast everywhere but means a write is visible in its home region before anywhere else, fine for ordinary profile edits and explicitly not fine for a deletion, hence treating deletions as a separate, higher-priority path rather than reusing the ordinary replication SLA. The pitfall to avoid is forgetting backups: a record purged from live storage and every region's cache but still sitting in a nightly backup snapshot is not actually deleted for compliance purposes, so the deletion workflow has to reach backups on a defined schedule too, not just live storage.
You experienced a 3-hour partial outage in the European region that increased latency and generated client errors. As the SRE lead, outline the post-incident review you would run: what data to collect, how to reconstruct the timeline, approaches to root cause analysis, remediation tasks, stakeholder communication, and preventative measures to add to the runbook.
Sample Answer
Direct answer
A post-incident review after a regional partial outage should reconstruct exactly what happened before assigning blame, quantify the real impact, find the root cause and its contributing factors, and turn findings into tracked remediation with named owners and dates.
Framework
- Data to collect: the timeline of events (deploys, config changes, alerts fired, on-call actions), metrics for the outage window versus a normal baseline (error rate, p50/p95/p99 latency, meaning the response time at the median and the slower 95th and 99th percentiles, resource saturation, meaning how close a resource like CPU is running to its limit, regional traffic split), sampled logs and distributed traces from affected requests, support ticket volume, and the cloud provider's own status page history if a dependency was involved.
- Reconstructing the timeline: normalize every timestamp to UTC first. Different teams logging in local time is a common source of a timeline that contradicts itself. Merge events from monitoring, deploy tooling, and the incident chat into one ordered log, and anchor it against trace IDs so you can see exactly which requests were touched by which change.
- Root cause approaches: stay blameless. Use "5 whys" for a single linear cause chain, or a fishbone (Ishikawa) diagram (a branching diagram that groups candidate causes into categories, like people, process, and systems, feeding into a single spine that points at the effect) when several contributing factors combined, for example a config push plus an already-saturated connection pool (the fixed set of reusable database connections a service shares across requests) plus a slow health check. Separate the triggering event from the underlying weaknesses that let it cascade into a 3-hour outage instead of a 10-minute blip.
- Remediation tasks: rank by likelihood of recurrence times blast radius (how much of the system or how many users a failure could affect) times effort, not by who argues loudest in the review. Give each item an owner and a due date, and mark a small subset as blocking before the incident can be closed.
- Stakeholder communication: engineering gets the full technical timeline; leadership gets impact numbers (duration, users affected, any SLA exposure, SLA meaning the contractual reliability commitment made to customers) plus the top fixes; customers get a short, plain-language summary of what they experienced, with no internal jargon and no premature root-cause claims.
- Runbook additions: turn each remediation into either an automated guardrail (a canary check, a tighter alert threshold) or an explicit manual step with a decision tree, so the next responder doesn't have to re-derive today's judgment calls under pressure.
Worked example
During the reconstructed timeline, the region's connection pool was sized for 500 concurrent connections. A downstream DNS change broke connection reuse, exhausting the pool in roughly 4 minutes and pushing p95 latency from 180ms to 3.2 seconds before an alert fired at the 6-minute mark. Detection, though, is the first 6 minutes of a 180-minute outage. A review that stops there has explained about 3 percent of the incident and left the other 97 percent unaccounted for, which is the single most common way a post-incident review produces cheap action items and no durable improvement. Slice the remaining time the same way you sliced the timeline and attach an item to each slice:
- Minutes 6 to 35, triage. The responder saw elevated latency and started on the application tier, because nothing in the alerting pointed at the connection pool. Item: emit pool utilisation and pool wait time as first-class metrics on the service dashboard, so the next responder starts where the problem is.
- Minutes 35 to 80, mis-scoped mitigation. Restarting application instances briefly drained the pool and made the graphs recover, so the team believed it was fixed and stopped investigating until latency came back. Item: write down "a mitigation that works twice and fails the third time is not a fix" as an explicit escalation trigger, because a partial mitigation that keeps working is more dangerous to a timeline than one that plainly fails.
- Minutes 80 to 150, cross-team diagnosis. Identifying the downstream DNS change required the network team, who were not engaged until the second escalation. Item: add the network on-call to the initial page for any regional latency incident rather than waiting for the application team to rule itself out first.
- Minutes 150 to 180, recovery and verification. The rollback itself was quick; confirming recovery across every affected client was not, because the queries had to be written during the incident. Item: pre-build the "is it actually better yet" dashboard so verification is a glance.
The 6-minute detection gap still earns an item of its own, lower the alert threshold and add a connection-pool-exhaustion signal instead of relying on latency alone to catch it, but rank it honestly: it is the cheapest item on the list and worth at most 6 of the 180 minutes. The expensive time went into triage and cross-team engagement, and a review that bills its whole finding to detection has optimised the part that was already nearly free.
Trade-offs and pitfalls
Rushing to a single root cause when several factors usually combined is the most common mistake. Remediation items with no owner or date quietly die in the backlog. Treating the review as a courtroom instead of a blameless exercise teaches people to hide facts in the next incident, which is the opposite of what the review is for.
Given inter-region RTT of 150ms, per-batch replication overhead of 5ms, and a sustained 1000 small writes/sec, propose batching and replication strategies to keep median replication lag below 500ms. Compute suggested batch sizes, commit intervals, and explain trade-offs in durability and tail latency.
Sample Answer
Direct answer
Batch writes on a fixed commit interval and pick that interval so that half the interval
(the average time a write waits to be included in a batch) plus the network transfer time
stays comfortably under the 500ms median lag target. With a 150ms round-trip time (RTT) and
5ms fixed overhead per batch, a commit interval of around 250ms produces roughly 280ms
median replication lag, leaving meaningful margin for the tail.
Working through the numbers
A write arriving at a random point during a fixed batching interval waits, on average, half
that interval before the batch is sent (some writes wait almost the full interval, some wait
almost none, averaging to half). With arrivals spread evenly across the interval that wait is
uniform between zero and T, whose median is also T/2, which is why the same T/2 term serves
for both the mean and the median here.
Before going further, pin down which quantity "replication lag" names, because the two common
definitions differ by half a round trip and that gap is 75ms in this problem, larger than any
other term you are about to tune. Definition one is measured at the source and is what almost
every monitoring system reports (PostgreSQL's replay_lag and the equivalents on most managed
engines work this way): the clock stops when the source receives the remote region's
acknowledgment that the write was applied, so it includes the return leg and costs a full
round trip. Definition two is measured at the target: the clock stops the moment the remote
copy actually holds the data, which costs only one-way transit, about RTT/2. These are
genuinely different numbers and a design review will ask which one the 500ms target refers to.
I'll size against definition one, because it is both the stricter figure and the one the
dashboards will show.
Once sent, then, a batch costs the full round trip plus the fixed per-batch overhead before
the source can record it as applied remotely.
To satisfy median lag under 500ms:
2T+150+5<500⇒T<690 msThat upper bound (690ms) leaves almost no margin for variance, so pick a commit interval
with real headroom instead of the theoretical maximum. Choosing T=250 ms:
That's 220ms of margin under the 500ms target, room to absorb network jitter, occasional
retries, or a brief backlog without breaching the target's median.
Under the target-side definition the same interval gives 125 + 75 + 5 = 205ms, so a design
sized against the stricter source-side metric clears the looser one with room to spare.
Sizing the other way round is the trap: an interval chosen against the 205ms figure and then
measured on the dashboard's 280ms figure is how a plan that looked compliant on paper misses
in production, and it is the same class of mistake as forgetting the T/2 term.
Batch size. At a sustained 1000 writes/second and a 250ms commit interval:
batch size≈1000×0.25=250 writes per batchThat's roughly 4 batches per second crossing the wide area network (WAN), each carrying
about 250 writes, and each incurring the fixed 5ms overhead once (not once per write), so
total per-batch overhead spent is about 4×5=20 ms of overhead per second,
negligible against a full second of wall-clock time.
Trade-offs in durability and tail latency
Durability. Batching for network efficiency and durability for crash recovery are
separate concerns and should use separate mechanisms. Each write should still be durably
recorded to a local write-ahead log (fsynced to disk) immediately on arrival, independent of
when it gets shipped to the remote region in a batch. That way, if the source process
crashes before a batch ships, the writes aren't lost, they're recoverable from the local log
and can be replayed once the process restarts, they're just delayed in reaching the remote
copy, which is exactly what "replication lag" describes, not a durability failure.
Tail latency. The 280ms median leaves 220ms of margin, but the 95th or 99th percentile
(p95/p99, the value that 95%/99% of samples fall under) will run higher than the median
whenever the actual RTT spikes (transient congestion) or a batch is delayed by contention on
the sending side. If the SLA that matters is actually a p99 target rather than median, a
250ms interval may need to shrink further, or the system needs a fallback (an out-of-band,
unbatched fast path for a small number of latency-critical writes) rather than tuning the
batch interval down for every write, which would give up the efficiency gains that batching
exists to provide.
Trade-offs and pitfalls
- A common mistake is computing lag as just RTT + overhead, forgetting the T/2 waiting
time inside the batch, that omission understates lag by over 100ms in this example and
can lead to picking an interval that looks compliant on paper but isn't in practice. - Shrinking the interval to reduce median lag increases the batch count and reduces the
amortization benefit batching exists for (compression ratio, fewer round trips); there's
a real efficiency cost to picking a very small T just to buy latency margin you may not
need. - Don't treat the 690ms theoretical ceiling as a target; it assumes RTT and overhead
never vary, which they will in a real network, hence recommending 250ms with real margin
rather than something closer to the ceiling.
Design a global multi-region analytics platform that ingests 10 billion events per day and supports both near-real-time metrics (1 minute latency for critical dashboards) and large-scale batch analytics. Account for cross-region aggregation, data residency laws (EU, India), consistent querying, replication, and failure isolation. Explain the trade-offs between eventual consistency and query correctness.
Sample Answer
Direct answer
Separate the ingestion/storage layer, which is region-local and append-only, from the query layer,
which lets each dashboard pick its own freshness-vs-correctness setting. "Near-real-time" and
"batch" analytics have genuinely different correctness requirements, and forcing one global
consistency model onto both wastes latency on the batch side and correctness on the real-time
side.
Structured elaboration
Cross-region aggregation. Each region ingests and pre-aggregates its own events locally (for
example, 1-minute rollups per metric) and ships only those rollups, not raw events, to a global
aggregator. Raw events stay local unless a specific, compliance-cleared pipeline needs them.
Ingestion: the telemetry path and the transactional path are not the same path. At the 115,700
events/sec computed below, the behavioral stream must not be written into an operational database
first just so it can be captured back out again: that makes every clickstream event pay for index
maintenance, multi-version row storage and vacuum inside an engine nothing queries for analytics.
Land that stream directly on a region-local, append-only commit log (a partitioned log such as
Kafka or Kinesis), which is already the shape the per-region pre-aggregation above assumes.
Change-data-capture (CDC, streaming every committed insert or update straight off the database's
write-ahead log) is the right mechanism for the much smaller transactional slice, orders,
subscriptions, account changes, where the analytics figure has to agree exactly with the system of
record. Used there it removes the dual-write problem (one copy to the app, one copy to analytics,
which silently diverge the first time one of the two writes fails) for the data where divergence is
expensive, without dragging high-volume telemetry through a transaction engine it has no business
touching. Say which path an event travels, because the guarantee differs and downstream has to
handle it: log-ingested telemetry is at-least-once and deduplicated on an event id in the pipeline,
while CDC-ingested rows inherit the source database's commit semantics and need no dedupe of their
own.
Data residency (EU, India). India's data-localization rules and the EU's General Data
Protection Regulation (GDPR) require raw event storage to stay in-region; only irreversibly
aggregated, non-personal counts may cross the border into the global rollup. Every event needs a
"residency class" decided at ingestion time, not retrofitted later once it's already replicated
somewhere it shouldn't be.
Consistent querying vs. query correctness. Near-real-time dashboards read the 1-minute
regional rollups directly and accept roughly 60-90 seconds of staleness. Definitive end-of-day or
monthly reports read from a separate batch layer only once every region's late-arriving,
out-of-order events have settled behind a multi-hour watermark (a cutoff time the pipeline
treats as "all data up to this point has now arrived," so anything trickling in after it
counts as late), because for a finance-facing report, correctness matters more than freshness.
Configurable per-region consistency. Expose a per-dashboard freshness-vs-correctness setting
rather than hardcoding one choice platform-wide: a marketing team's live campaign dashboard wants
freshness over completeness, a finance team's revenue-by-region report wants the opposite.
Failure isolation. A region's ingestion outage should mark that region's own dashboards stale,
not silently drop it from the global rollup and corrupt the total with a partial sum. The aggregator tracks a per-region "as-of" watermark (the same "data is complete up to this
point in time" marker described above) and surfaces it.
Worked example
10 billion events/day is about 115,700 events/sec on average. Split unevenly across 4 regions
(US 50%, EU 30%, India 15%, APAC 5%), that's roughly 58,000/34,700/17,400/5,800 events/sec. A
1-minute rollup of 200 metrics per region ships 200 numbers per minute per region to the global
aggregator, instead of about 3.5 million raw US events in that same minute: a compression ratio on the
order of 17,000-to-1 on the cross-region link (roughly 3.5 million divided by 200; a quick
mental estimate of 10,000-to-1 undercounts the real savings by nearly half), which is the
entire reason cross-region aggregation is tractable at this event volume.
Trade-offs & pitfalls
Pre-aggregating at the edge means a bug fix to a metric's definition requires re-deriving it from
raw data wherever that raw data still lives, so keep raw events for a defined retention window
(30-90 days) even though the rollup is what's normally queried. Offering "configurable
consistency" without a visible staleness indicator on the dashboard just moves the confusion from
the backend to the user, who will still ask why two dashboards disagree.
Unlock Full Question Bank
Get access to all Multi-Region and Geo-Distributed Systems interview questions and detailed answers.
Sign in to ContinueJoin thousands of developers preparing for their dream job.