Setup:
1. **Enable multi-region writes or single-write.** Single-write-region is simpler and cheaper; multi-region writes give lower write latency everywhere but introduce conflict resolution. Default to single-write unless you have measured write latency pain.
2. **Add regions** in the portal (Replicate data globally) or `az cosmosdb update --locations regionName=[r2] failoverPriority=1`. Priority 0 = current write region. Order the rest by preference.
3. **Consistency level.** Strong is not available multi-region; Bounded staleness is the usual pick for correctness-sensitive workloads, Session for the common case, Eventual for max availability. This is account-level and affects every SDK call.
4. **Automatic failover.** Enable it with a grace period (e.g. 10 minutes): if the write region is down longer than the grace period, the next priority region promotes itself. Without it, failover is manual.
Test it (do this in staging, quarterly):
- `az cosmosdb failover-priority-change` to force the write region to move. Watch the app: SDKs discover the new write region automatically, but in-flight writes during the cutover can fail - the app must retry.
- Measure: RTO is minutes with automatic failover; RPO is bounded by the consistency level (bounded staleness gives you a number).
Traps:
- **SDK region preference.** Set `preferred_locations` in the client so reads stay local; without it, reads may cross the world.
- **Failover during deployment.** Do not run region changes while a data migration runs.
- **Cost.** Every region stores a full copy and you pay RU/s per region. Two regions roughly doubles the bill.
Verify: after a manual failover, writes succeed to the new region, reads show the data, and failover priority order in the portal matches intent.