Overview

When your business grows from “serving one city” to “serving the entire country” or even “serving globally,” single-datacenter architecture hits two hard constraints: latency from distance and single point of failure risk. Multi-region active-active architecture is the engineering solution to both problems.

But active-active architecture is one of the most complex topics in SRE — it’s not simply “deploy the service in two datacenters.” It involves a series of deep engineering challenges: data consistency, traffic routing, failover, and operational complexity. Done right, system availability goes from 99.9% to 99.99%; done wrong, the multi-active architecture itself becomes the biggest source of failures.

This article systematically covers the reliability design of multi-active architecture — covering patterns, data consistency challenges, traffic switching strategies, disaster recovery RTO/RPO design, cross-region monitoring, and failover drills.

For in-depth discussions on multi-active architecture, see Google SRE Book - Disaster Preparedness and AWS - Multi-Region Active-Active Architecture.

1. Why Multi-Active Architecture

Limitations of Single-Datacenter Architecture

Single-datacenter architecture:
                                           ┌── App Server ×N
  User ──→ DNS/CDN ──→ Load Balancer ─────┼── App Server ×N
                                           └── App Server ×N
                                           ┌─────────┴─────────┐
                                           │   Database (Primary-Replica)   │
                                           └───────────────────┘

Problems:
  1. If datacenter loses power/network → entire site unavailable
  2. High latency for cross-region users (Beijing to Guangzhou ~30ms RTT)
  3. Capacity limited by a single datacenter

Drivers for Multi-Active Architecture

DriverDescriptionPriority
Disaster recoveryBusiness continuity during datacenter-level failuresHigh
Low latencyServe users from nearby regions, reducing access latencyHigh
Capacity scalingBreak through single-datacenter capacity limitsMedium
ComplianceData must be stored in specific regionsIndustry-dependent
DR drill requirementsRegulators require cross-datacenter disaster recovery capabilityIndustry-dependent

Key Disaster Recovery Metrics

Before designing a multi-active architecture, you must define two disaster recovery metrics:

MetricFull NameMeaningDesign Impact
RTORecovery Time ObjectiveMaximum allowed recovery time after failureShorter RTO → faster failover needed → prefer automatic switching
RPORecovery Point ObjectiveMaximum allowed data loss after failureRPO=0 → requires synchronous replication → performance tradeoff
RTO and RPO relationship:

Timeline:
  Normal operation │←─────── Failure occurs ───────→ Recovered
            │                            │
            │←── RPO ──→│               │
            │  Data loss range           │
            │                            │
            │←────── RTO ──────────────→│
               Service unavailability time

Different RTO/RPO targets correspond to different architecture choices:

RTO TargetRPO TargetArchitecture ChoiceCost
< 1 minute0Same-city active-active (synchronous replication)High
< 5 minutes< 1 minuteSame-city active-standby (semi-synchronous replication)Medium
< 30 minutes< 5 minutesRemote active-standby (asynchronous replication)Low
< 4 hours< 1 hourRemote cold standby (periodic backup)Lowest

2. Multi-Active Architecture Patterns

Pattern 1: Active-Standby

  User ──→ DNS ──→ Primary Datacenter (Active)
                      ├── App Server
                      ├── DB (Primary)
                      └── ↓ Asynchronous replication
                  Standby Datacenter (Standby)
                      ├── App Server (standing by)
                      └── DB (Standby)

How it works: Under normal conditions, only the primary datacenter serves traffic. The standby datacenter stays synchronized via asynchronous replication. When the primary fails, traffic switches to the standby.

AdvantagesLimitations
Relatively simple architectureStandby datacenter idle, low resource utilization
Data consistency is easy to guaranteeAsynchronous replication has lag, switching may lose data (RPO > 0)
No write conflictsLonger failover time (RTO from minutes to tens of minutes)
Lower costStandby datacenter carries no traffic, hard to validate availability

Suitable for: Medium-criticality business with RTO < 30 minutes and tolerable minor data loss.

Pattern 2: Same-City Active-Active

  User ──→ DNS ──→ Load Balancer (weighted traffic split)
           ┌──────────┴──────────┐
           ↓                     ↓
     Datacenter A (Active)   Datacenter B (Active)
     ├── App Server          ├── App Server
     ├── DB (Primary)        ├── DB (Replica)
     └── Synchronous replication ←─────────┘

How it works: Both datacenters serve traffic simultaneously. Databases are kept consistent through synchronous replication. If either datacenter fails, the other continues serving.

AdvantagesLimitations
High resource utilizationSynchronous replication has performance overhead
RTO approaches 0Datacenter distance is limited (typically < 100km)
RPO = 0Requires low-latency dedicated connectivity
Both datacenters carry trafficHigh architecture complexity

Suitable for: Core business with RTO < 1 minute, RPO = 0 (e.g., financial transactions).

Pattern 3: Geo-Distributed Active-Active

  User ──→ Global DNS (geo-based routing)
     ┌─────────┼─────────┐
     ↓         ↓         ↓
   Beijing    Shanghai   Overseas
   ├── App    ├── App    ├── App
   ├── DB     ├── DB     ├── DB
   └──┬───────┴──┬──────┘
      │ Async replication  │
      └──────────┘

How it works: Multiple regions serve traffic simultaneously. Each region has a complete database replica. Data is synchronized across regions via asynchronous replication.

AdvantagesLimitations
Serves users nearby, low latencySignificant data consistency challenges (CAP theorem)
Any region failure doesn’t affect othersWrite conflicts need resolution
Horizontal capacity scalingExtremely high operational complexity
Global coverageHighest cost

Suitable for: Global businesses (e.g., cross-border e-commerce, global SaaS).

Pattern Selection Decision Tree

Need multi-datacenter disaster recovery?
  ├─ Yes → What are RTO and RPO requirements?
  │   │
  │   ├─ RTO < 1min, RPO = 0
  │   │   → Same-city active-active (synchronous replication)
  │   │   → Requires: low-latency dedicated link, synchronous replication database
  │   │
  │   ├─ RTO < 30min, RPO < 1min
  │   │   → Remote active-standby (asynchronous replication)
  │   │   → Requires: asynchronous replication, automatic failover
  │   │
  │   └─ RTO < 4h, RPO < 1h
  │       → Remote cold standby (periodic backup)
  │       → Requires: backup system, manual recovery process
  └─ Need global low latency?
      → Geo-distributed active-active (unit-based architecture)
      → Requires: data sync solution, write conflict resolution, global routing

3. Data Consistency Challenges

CAP Theorem Constraints

The most fundamental challenge in multi-active architecture comes from the CAP theorem:

In a distributed system, Consistency, Availability, and Partition Tolerance can only satisfy two of the three simultaneously.

Since network partitions (Partition) are unavoidable, multi-active architecture must choose between C and A:

ChoiceMeaningArchitecture PatternSuitable For
CPGuarantee consistency, sacrifice availabilitySynchronous replicationFinancial transactions
APGuarantee availability, sacrifice consistencyAsynchronous replicationSocial media, content delivery

Data Replication Scheme Comparison

Replication SchemeConsistencyPerformanceRPOSuitable For
SynchronousStrongLow (waits for remote confirmation)0Finance, payments
Semi-synchronousNear-strongMedium (at least one remote confirms)≈0Core business
AsynchronousEventually consistentHigh (no remote wait)>0General business
No replicationN/AHighestTotal lossReconstructable data

Data Conflict Resolution

In multi-active architecture, multiple regions may simultaneously modify the same data, causing conflicts:

Scenario: User modifies profile simultaneously in Beijing and Shanghai

  14:00:00  Beijing: User changes name to "Zhang San" → Written to Beijing DB
  14:00:01  Shanghai: User changes name to "Li Si" → Written to Shanghai DB
  14:00:05  Async replication: Beijing → Shanghai ("Zhang San" overwrites "Li Si")
  14:00:06  Async replication: Shanghai → Beijing ("Li Si" overwrites "Zhang San")
  → Data conflict! Final state is uncertain

Conflict resolution strategies:

StrategyPrincipleAdvantageLimitation
Last Write Wins (LWW)Use timestamps, latest overwritesSimpleClock skew causes issues
Vector clocksTrack causal relationships, detect conflictsPrecise conflict detectionComplex implementation
Application-level resolutionApplication understands business semantics, custom mergeSemantically correctCustom per business
Unit-basedData belongs to user’s home region, avoid cross-region writesFundamentally avoids conflictsRouting must be accurate

Unit-Based Architecture

Unit-based architecture is the most elegant solution to data conflicts in multi-active systems — it prevents cross-region write conflicts at the source.

Unit-based architecture:

  User ──→ Routing layer (route to home unit by user ID)
     ┌─────────┼─────────┐
     ↓         ↓         ↓
   Unit-Beijing  Unit-Shanghai  Unit-Shenzhen
   ├── App    ├── App    ├── App
   ├── DB     ├── DB     ├── DB
   └── Data sharded by user

   User A's data is only read/written in Unit-Beijing
   User B's data is only read/written in Unit-Shanghai
   → No write conflicts

Unit routing rules:

# Unit routing configuration
unit_routing:
  rule: "hash(user_id) % unit_count"
  
  units:
    - name: "unit-bj"
      region: "beijing"
      user_range: "0-33%"
      
    - name: "unit-sh"
      region: "shanghai"
      user_range: "33-66%"
      
    - name: "unit-sz"
      region: "shenzhen"
      user_range: "66-100%"

  # User's home unit is determined on first access
  # All subsequent requests are routed to that unit

Challenges of unit-based architecture:

  1. Cross-unit queries: User A follows User B, but B is in another unit — requires cross-unit queries or data synchronization
  2. Unit scaling: Adding or removing units requires data redistribution
  3. Failover: When a unit fails, its users need to be migrated to another unit

4. Traffic Switching Strategies

Global Traffic Management

Multi-active architecture requires a global traffic management layer to route users to the correct region:

User request
Global DNS / GSLB (Global Server Load Balancing)
  ├── Route by geographic proximity
  ├── Route by health status
  ├── Route by capacity weight
  └── Auto-failover on failure

Traffic Switching Scenarios

ScenarioTriggerSwitching MethodRTO
Planned switchoverMaintenance window, architecture migrationManual, gradual traffic shiftingN/A
Single-datacenter failureDatacenter network outage/power lossAuto-switch to standby datacenter< 5min
Region failureEntire region unavailableAuto-switch to other regions< 10min
Degraded failoverSingle datacenter performance degradationPartial traffic switch< 5min

DNS Switching

# DNS failover configuration
dns_failover:
  primary:
    record: "api.example.com"
    target: "1.2.3.4"          # Primary datacenter IP
    health_check: "https://api.example.com/healthz"
    check_interval: 10s
    
  failover:
    target: "5.6.7.8"          # Standby datacenter IP
    trigger: "primary health check failed 3 consecutive times"
    ttl: 30s                   # Short DNS TTL for faster switching
    
  # Note: DNS switching has TTL cache delay
  # Clients may cache old IPs; may take up to TTL to take effect

Limitations of DNS switching:

  • DNS TTL caching causes non-instant switching
  • Some clients don’t honor TTL
  • Cannot precisely control traffic proportions

Application-Layer Traffic Switching

# Application-layer traffic routing (more precise)
app_level_routing:
  gateway:
    type: "API Gateway / Service Mesh"
    
  routing_rules:
    normal:
      - region: "beijing"
        weight: 50%
      - region: "shanghai"
        weight: 50%
    
    failover:
      trigger: "beijing region health check failed"
      action:
        - region: "beijing"
          weight: 0%            # Immediately drain
        - region: "shanghai"
          weight: 100%          # Full switch
      speed: "instant"          # App-layer switching has no DNS caching issue
    
    canary_failover:
      trigger: "beijing region degraded (latency > 1s)"
      action:
        - region: "beijing"
          weight: 25%           # Degrade rather than full drain
        - region: "shanghai"
          weight: 75%

Traffic Switching Best Practices

traffic_switching_best_practices:
  before_switch:
    - "Verify target datacenter health status"
    - "Confirm data sync lag is within acceptable range"
    - "Notify relevant teams"
    - "Prepare rollback plan"

  during_switch:
    - "Gradual switching, not all at once"
    - "Continuously monitor during switching"
    - "If anomalies occur, immediately roll back"

  after_switch:
    - "Verify service is normal"
    - "Observe for at least 15 minutes"
    - "Update DNS records"
    - "Notify all teams that switching is complete"

  switch_sequence:
    1: "Reduce source datacenter traffic weight (100% → 90%)"
    2: "Observe if target datacenter can handle 10% traffic"
    3: "Continue reducing source weight (90% → 50%)"
    4: "Observe target datacenter performance at 50% traffic"
    5: "Complete switch (50% → 0%)"
    6: "Source datacenter fully drained"

5. Disaster Recovery RTO/RPO Design

RTO Design

RTO (Recovery Time Objective) depends on failure detection time and switching time:

RTO = Failure detection time + Decision time + Switching time + Verification time

Example:
  Failure detection: 30 seconds (health check 3 failures × 10s interval)
  Decision time: 30 seconds (automated decision script)
  Switching time: 60 seconds (DNS update + traffic switch)
  Verification time: 60 seconds (health check confirmation)
  → RTO ≈ 3 minutes

Strategies to reduce RTO:

StrategyMeasureRTO Improvement
Auto-detectionHealth checks + auto-alertingDetection from minutes to seconds
Auto-failoverFully automated failover without human interventionDecision from minutes to seconds
Pre-warmed standbyStandby datacenter kept in running stateSwitching from minutes to seconds
Auto-verificationAutomated health verification scriptsVerification from minutes to seconds

RPO Design

RPO (Recovery Point Objective) depends on data replication lag:

RPO = Data replication lag

Synchronous replication: RPO = 0 (data synced in real time)
Asynchronous replication: RPO = Replication lag time (typically 1-60 seconds)

Strategies to reduce RPO:

StrategyMeasureRPO Improvement
Synchronous replicationWrites require confirmation from at least 2 datacentersRPO = 0
Semi-synchronous replicationAt least 1 replica confirmsRPO ≈ 0
Shorter replication intervalMore frequent replicationRPO from minutes to seconds
Monitor replication lagAlert when replication lag exceeds thresholdDoesn’t reduce RPO but enables timely alerting

RTO/RPO Monitoring

# RTO/RPO monitoring metrics
disaster_recovery_monitoring:
  rto_related:
    - metric: "health_check_failure_count"
      alert: "> 3 consecutive failures"
      action: "trigger automatic failover"
    
    - metric: "failover_execution_time"
      target: "< 60s"
    
    - metric: "service_recovery_time"
      target: "< 5min (RTO target)"

  rpo_related:
    - metric: "replication_lag_seconds"
      alert: "> 10s"
      action: "warning"
      critical: "> 60s"
    
    - metric: "replication_lag_bytes"
      alert: "> 10MB"
      
    - metric: "data_loss_on_failover"
      target: "0 (RPO target)"
# Prometheus monitoring for replication lag
# MySQL primary-replica replication lag
mysql_slave_status_seconds_behind_master > 10

# PostgreSQL replication lag
pg_replication_lag > 10

# Redis replication lag
redis_replication_offset_diff > 1024000

6. Cross-Region Monitoring

Monitoring Architecture

Multi-active architecture requires a monitoring system with a global perspective:

Monitoring architecture:

  Beijing Datacenter            Shanghai Datacenter
  ├── Prometheus                ├── Prometheus
  ├── Node Exporter             ├── Node Exporter
  ├── App Metrics               ├── App Metrics
  └── ↓ remote_write            └── ↓ remote_write
          │                        │
          └────────┬───────────────┘
           Central Prometheus / Thanos
           ┌───────┼───────┐
           ↓       ↓       ↓
         Grafana  AlertManager  Long-term storage

Key Monitoring Dimensions

multi_region_monitoring:
  # 1. Per-region service health
  per_region:
    - "Per-region service availability"
    - "Per-region latency (P50/P95/P99)"
    - "Per-region error rate"
    - "Per-region traffic distribution"

  # 2. Cross-region data synchronization
  cross_region:
    - "Database replication lag"
    - "Message queue cross-region sync lag"
    - "Cache sync lag"
    - "Replication channel health status"

  # 3. Global view
  global:
    - "Global availability (weighted average across all regions)"
    - "Global SLO achievement status"
    - "Inter-region traffic distribution"
    - "DNS resolution distribution"

  # 4. Disaster recovery readiness
  dr_readiness:
    - "Standby datacenter health status"
    - "Is data sync lag within RPO range?"
    - "Are failover scripts available?"
    - "Time since last failover drill"

Global Monitoring Dashboard

# Global monitoring dashboard design
global_dashboard:
  row_1_global_overview:
    - panel: "Global service availability"
      query: "avg by (region) (slo:availability:rate30d)"
    - panel: "Global traffic distribution"
      query: "sum by (region) (rate(http_requests_total[5m]))"
    - panel: "Global error rate"
      query: "sum by (region) (rate(http_requests_total{status=~'5..'}[5m]))"

  row_2_replication_health:
    - panel: "Database replication lag"
      query: "max by (region) (mysql_slave_status_seconds_behind_master)"
      threshold: "10s (warning), 60s (critical)"
    - panel: "Message queue sync lag"
      query: "max by (region) (mq_replication_lag_seconds)"

  row_3_dr_readiness:
    - panel: "Per-datacenter health status"
      type: "status_map"
      query: "up by (region, instance)"
    - panel: "RPO status"
      type: "gauge"
      query: "max(replication_lag_seconds)"
      threshold: "green < 10s, yellow 10-60s, red > 60s"
    - panel: "Last drill time"
      type: "stat"
      query: "time() - last_drill_timestamp"

7. Failover Drills

Why Drills Are Needed

The biggest risk of multi-active architecture is not “can’t failover,” but “thinking you can failover when you actually can’t.” A disaster recovery plan that hasn’t been tested through real drills is just wishful thinking.

Real-world case:
  A company invested millions in remote disaster recovery, with no drills for three years.
  When a real failure occurred and they tried to switch, they found:
    - DNS switching scripts were outdated and non-functional
    - Standby datacenter database version mismatched primary
    - SSL certificates had expired
    - Standby datacenter application configuration was incomplete
  → Disaster recovery was effectively non-existent

Drill Types

TypeMethodRiskFrequency
Tabletop exerciseDiscussion-based scenario simulationNoneQuarterly
Simulation switchSimulate failover in non-production environmentNoneMonthly
Production traffic shiftShift partial traffic in productionLowMonthly
Full failoverComplete switch to standby datacenter in productionMediumEvery 6 months
Chaos injectionSimulate datacenter-level failure, validate auto-failoverMedium-HighAnnually

Full Failover Drill Process

# Multi-Active Failover Drill

## Drill Goal
Validate the complete process of switching from Beijing to Shanghai datacenter, confirming RTO < 5min, RPO < 10s.

## Prerequisites
- [ ] Shanghai datacenter health status is normal
- [ ] Data sync lag < 5s
- [ ] Failover scripts have been validated in simulation
- [ ] Rollback plan is prepared
- [ ] Relevant teams have been notified
- [ ] Off-peak time window selected (2:00-4:00 AM)

## Drill Process

### Phase 1: Pre-check (T-30min)
1. Verify Shanghai datacenter service health
   ```bash
   curl -s https://api-sh.example.com/healthz
  1. Confirm data sync lag
    # MySQL replication lag
    mysql -h sh-db -e "SHOW SLAVE STATUS\G" | grep Seconds_Behind_Master
    # Expected: < 5s
    
  2. Confirm Shanghai datacenter capacity can handle full traffic

Phase 2: Traffic Switch (T+0)

  1. Adjust DNS weights from Beijing100%/Shanghai0% to Beijing90%/Shanghai10%
    ./update_dns_weights.sh --bj 90 --sh 10
    
  2. Observe for 2 minutes, confirm Shanghai datacenter handles traffic normally
  3. Continue adjusting: Beijing50%/Shanghai50%
  4. Observe for 5 minutes
  5. Complete switch: Beijing0%/Shanghai100%

Phase 3: Verification (T+10min)

  1. Verify service availability
    curl -s https://api.example.com/healthz
    # Expected: 200 OK
    
  2. Verify SLO metrics
    # Query Prometheus
    curl -s "http://prometheus:9090/api/v1/query?query=slo:availability:rate5m"
    # Expected: > 99.9%
    
  3. Verify user experience (black-box monitoring)

Phase 4: Switch Back (T+30min)

  1. Reverse the traffic switch back to Beijing
  2. Confirm Beijing datacenter is serving normally

Phase 5: Drill Retrospective (T+1day)

  1. Record drill timeline
  2. Evaluate whether RTO and RPO targets were met
  3. Log discovered issues as improvement items
  4. Update failover documentation

### Automated Failover

```yaml
# Automated failover configuration
auto_failover:
  enabled: true
  trigger:
    condition: "primary region health check failed 3 consecutive times"
    health_check:
      url: "https://api-bj.example.com/healthz"
      interval: 10s
      timeout: 5s
      failure_threshold: 3

  pre_failover_checks:
    - "standby region health: OK"
    - "replication lag < 10s"
    - "standby capacity > 100% of current traffic"

  failover_steps:
    1:
      action: "update DNS weights"
      from: "bj:100,sh:0"
      to: "bj:0,sh:100"
      timeout: 30s
    
    2:
      action: "promote standby DB to primary"
      command: "./promote_standby_db.sh --region sh"
      timeout: 60s
    
    3:
      action: "verify service health"
      command: "./verify_service.sh --region sh"
      timeout: 60s
    
    4:
      action: "notify teams"
      command: "./notify.sh --event auto_failover --to all"

  rollback:
    condition: "verification failed or service not healthy after 5 min"
    action: "revert DNS weights to original"

8. Common Pitfalls of Multi-Active Architecture

Pitfall 1: “Fake Active-Active”

Fake active-active:
  Both datacenters have applications deployed, but only one datacenter has the database.
  Datacenter A fails → Datacenter B's application can't access the database → entire site unavailable.

  This is not active-active; it's just "dual deployment."
  
True active-active:
  Both datacenters have complete application + database replicas.
  Either datacenter fails → the other continues independently.

Pitfall 2: Ignoring Dependent Services

Scenario:
  Applications are made active-active, but dependent third-party services (e.g., SMS gateway, payment channel) are single-pointed.
  Datacenter fails → Application switches to standby → but standby can't access third-party services → still unavailable.

Lesson:
  Active-active scope must cover all critical dependencies, including third-party services.
  Third-party services also need backup plans (e.g., multiple SMS providers).

Pitfall 3: DNS Caching Causes Ineffective Switching

Scenario:
  DNS TTL is set to 1 hour.
  Datacenter fails, DNS is switched, but clients have cached old IPs.
  For 1 hour, some users still access the failed datacenter.

Lesson:
  DNS TTL for failover scenarios should be set to 30-60 seconds.
  Or use application-layer routing (API Gateway/Service Mesh) to bypass DNS caching.

Pitfall 4: Data Inconsistency Causes Post-Switch Data Corruption

Scenario:
  Asynchronous replication lag is 30 seconds.
  Primary datacenter fails and forced switch loses the last 30 seconds of data.
  Users find their just-submitted orders have disappeared.

Lesson:
  Define RPO targets clearly and check replication lag before switching.
  If replication lag exceeds RPO, wait rather than switch immediately.
  For RPO=0 scenarios, synchronous replication must be used.

Pitfall 5: Never Drilling

Scenario:
  Built multi-active disaster recovery but never drilled.
  During a real failure, found that failover scripts were expired, configurations inconsistent, certificates expired.

Lesson:
  A disaster recovery plan that hasn't been drilled equals no disaster recovery.
  Do a full failover drill at least every 6 months.
  Do a partial traffic switch validation monthly.

9. Cost Analysis of Multi-Active Architecture

multi_region_cost_analysis:
  infrastructure:
    dual_active:
      compute: "2x (both datacenters need full compute resources)"
      storage: "2x + replication bandwidth"
      network: "Dedicated link / interconnect bandwidth"
      
    active_standby:
      compute: "1.5x (standby can be scaled down)"
      storage: "2x"
      network: "Replication bandwidth"

  operational:
    engineering: "Engineers with multi-active architecture experience"
    monitoring: "Cross-region monitoring system"
    testing: "Regular drill costs"

  hidden_costs:
    - "Business complexity from data replication lag"
    - "Time cost of cross-region debugging and troubleshooting"
    - "Additional work for data compliance auditing"
    - "Training cost for team to master multi-active operations skills"

  roi_analysis:
    benefit: "Avoiding business losses from datacenter-level failures"
    question: "Annual probability of datacenter failure × failure loss vs multi-active annual cost"
    typical: "Core business is worth multi-active; non-core business can use active-standby"

Summary

Multi-active architecture is one of the most complex yet highest-value architecture patterns in the SRE framework. Key points:

  1. Define RTO/RPO targets clearly: All multi-active design starts from RTO/RPO targets — don’t do multi-active just for the sake of it
  2. Choose the right pattern: Active-standby, active-active, and multi-active each have their applicable scenarios — more complex isn’t better
  3. Data consistency is the core challenge: The CAP theorem cannot be bypassed — make an explicit choice between consistency and availability
  4. Unit-based architecture is the elegant solution for write conflicts: Route by user’s home region to prevent cross-region writes at the source
  5. Traffic switching should be gradual: Don’t switch all at once — shift traffic gradually and verify continuously
  6. Cross-region monitoring provides a global view: Need to see health status and data sync status across all regions
  7. Regular drills are mandatory: Disaster recovery that hasn’t been drilled equals no disaster recovery

Final reminder: Multi-active architecture is not a silver bullet. While improving availability, it also brings enormous architecture complexity and operational cost. Before deciding to go multi-active, ask yourself: is single-datacenter + fast recovery already sufficient? Multi-active architecture is only worth the investment when single-datacenter RTO/RPO truly cannot meet business requirements.

Remember the fundamental principle of architecture design: use the simplest architecture that meets reliability requirements. Complexity itself is the enemy of reliability.

References & Acknowledgments

This article referenced the following materials during writing. We thank the original authors for their contributions:

  1. Google SRE Book - Disaster Preparedness — Google SRE Team, referenced for Google SRE Book - Disaster Preparedness
  2. AWS - Multi-Region Active-Active Architecture — Amazon Web Services, referenced for AWS - Multi-Region Active-Active Architecture