# Regional Partitioning

## 1. A Different Reason to Split Data: Geography, Not Load

Every scaling technique covered so far in this group — table partitioning, replication, sharding — splits or copies data primarily to handle *volume*: too many rows, too many writes, too many reads for one server. Regional partitioning splits data for a different reason entirely: **where the data (and its users) physically are**, driven by two forces that have nothing to do with row count:

- **Latency** — a user in Tokyo reading data stored only in a Virginia data center pays a genuine speed-of-light round-trip cost (100-200ms+) no amount of caching or indexing removes, because the physical distance the request has to travel is the bottleneck, not database query time.
- **Data residency / compliance** — regulations (GDPR in the EU, and similar region-specific rules elsewhere) can require that certain categories of user data physically remain within a specific jurisdiction's borders, which is a legal constraint, not a performance one — a system can be arbitrarily fast and still be non-compliant if the data lives in the wrong country.

## 2. The Two Base Topologies

**Single-write-region, with regional read replicas**: one region is designated the source of truth for writes; other regions hold read replicas (the same mechanism as `02-replication/`, just deployed geographically far apart instead of in the same data center).

```
   [US-EAST: LEADER]  ── writes accepted here only
        │  replicate (async, cross-region -- lag is now tens to hundreds of ms, not single-digit ms)
   ┌────┴─────┐
   ▼          ▼
[EU-WEST     [APAC
 replica]     replica]
   ▲              ▲
 EU reads      APAC reads
 (fast)        (fast)

 EU/APAC writes still cross the ocean to US-EAST (slow) -- this topology only
 speeds up READS for non-leader regions, exactly like plain replication
```

This solves regional *read* latency cheaply (it's the same replication mechanism already covered) but does nothing for regional *write* latency — a write from a user in Tokyo still has to reach the single write-region, incurring the full round trip, every time.

**Active-active multi-region**: more than one region accepts writes independently, each serving its local users' writes with local latency.

```
[US-EAST: writable]  <---sync--->  [EU-WEST: writable]  <---sync--->  [APAC: writable]

 US writes: fast (local)
 EU writes: fast (local)
 APAC writes: fast (local)

 ...but the SAME row can now be written in two regions independently, needing
 a conflict-resolution strategy (see section 4) once those writes are synced
```

Active-active solves write latency for every region, at the cost of introducing the hard problem replication and single-leader sharding both conveniently avoided: **the same piece of data can be modified in two places at once**, and the system needs a defined answer for what happens when those two modifications disagree.

![A single write region with regional read replicas gives fast local reads but remote writes, while active-active accepts local writes everywhere at the cost of conflicts](diagrams/01-regional-topologies.svg)

## 3. Data Residency as a Partitioning Key

When compliance requires certain users' data to stay within a region, that requirement itself becomes the effective partition key — structurally identical to `01-database_partitioning/` section 2's list partitioning, just with the "partitions" being entire regional database deployments instead of tables on one server:

```
EU user data  -> lives ONLY in an EU-region database (GDPR data-residency requirement)
US user data  -> lives ONLY in a US-region database
APAC user data -> lives ONLY in an APAC-region database

A user's home region is typically fixed at signup and rarely changes -- unlike a hash-sharded
key, this partition key is a business/legal fact about the user, not a load-balancing choice
```

This can be combined with either topology above: a company can run single-write-region *within* each residency zone (EU writes go to an EU leader, US writes to a US leader, each independently) rather than needing full active-active — residency-driven regional partitioning and load-driven active-write-scaling are separate concerns that happen to often get solved by the same physical deployment shape.

## 4. Conflict Resolution in Active-Active Systems

When two regions can independently accept a write to logically the same record, the system needs a rule for reconciling divergent writes once they sync. Common approaches, roughly in order of how much they give up:

- **Last-write-wins (LWW)** — attach a timestamp to every write; when two versions of a record conflict, the one with the later timestamp wins, the other is silently discarded. Simple to implement, but genuinely **loses data** — whichever write lost is gone, with no merge, which is unacceptable for some kinds of data (e.g. discarding one of two conflicting inventory decrements is a real bug) and perfectly fine for others (e.g. "last user to update their own display name wins" is a reasonable UX).
- **Application-level merge logic** — instead of picking one write and discarding the other, the application defines how to combine two conflicting versions (e.g. a shopping cart merges by union of items rather than picking one cart wholesale). Requires custom logic per data type; there's no generic "reconcile any two writes" algorithm.
- **CRDTs (Conflict-free Replicated Data Types)** — data structures specifically designed so that concurrent updates can always be merged automatically and deterministically without losing information or needing custom per-field merge logic (e.g. a "grow-only counter" that only ever increments, so merging two divergent copies is just taking the max — no conflict is even possible by construction). Powerful but constrains which operations are available; not every data model fits a CRDT.
- **Avoid the conflict by partitioning writes**: the residency-driven approach from section 3 — if EU writes and US writes never touch the same rows in the first place (different users, different partition), there's no conflict to resolve at all. This is the cheapest option whenever it's actually available, which is precisely why residency-driven regional partitioning and active-active are so often combined rather than active-active being reached for globally.

This entire problem is a direct instance of the CAP theorem tradeoff (`distributed-systems/fundamentals/09-cap_theorem/`): during a network partition between regions, an active-active system choosing to keep accepting local writes in both regions (favoring availability) is explicitly accepting that it will need conflict resolution later, rather than blocking writes in one region until connectivity is restored (favoring consistency).

## 5. Common Pitfalls

1. **Defaulting to active-active without a real write-latency requirement** — if reads dominate and writes are infrequent/not latency-sensitive, single-write-region with regional read replicas (section 2's first topology) gets most of the benefit for a fraction of the conflict-resolution complexity.
2. **Treating data residency as a performance optimization instead of a legal requirement** — a residency boundary must be enforced even if it's occasionally less performant than an alternative layout; conflating the two leads to "optimizing" a boundary out of existence and creating a compliance violation.
3. **Choosing last-write-wins for data where losing a write is a real bug** (inventory counts, financial balances, anything where "the discarded write never happened" is unacceptable) — LWW is appropriate for low-stakes, single-owner-typically fields, not shared mutable counters or records with real business consequences.
4. **Ignoring cross-region replication lag when reasoning about consistency** — the same read-your-own-writes problem from `02-replication/` section 4 applies here, amplified: cross-region lag is routinely tens to hundreds of milliseconds, not single-digit milliseconds, making stale-read windows far more noticeable to users.
5. **Assuming CRDTs solve every conflict scenario** — they solve conflicts for the specific operations they're built for (counters, sets with defined merge semantics, etc.); arbitrary application data doesn't automatically get conflict-free merging just by calling it a CRDT.

## 6. Quick Reference

```
Regional partitioning motivations: LATENCY (physical distance) + DATA RESIDENCY (compliance)
  -- distinct from every other scaling technique in this group, which is about volume, not geography

Single-write-region + regional read replicas: fast regional READS, writes still cross-region (slow)
Active-active multi-region: fast regional WRITES everywhere, needs conflict resolution

Data residency: a region requirement AS a partition key -- fixed by user's legal jurisdiction

Conflict resolution (active-active): LWW (simple, loses data) | app-level merge (custom, no loss)
  | CRDTs (automatic + safe, but constrains data model) | avoid via residency-based write partitioning

Ties to distributed-systems/fundamentals/09-cap_theorem/: active-active during a partition = choosing
availability over consistency, and paying for it later with conflict resolution
