Back to Blog

Multi-Region Frontend Delivery Architecture

Introduction

Deploying a frontend to a single region and putting a CDN in front of it isn't multi-region architecture—it's single-region architecture with caching. True multi-region delivery means your users hit compute, APIs, and data that are geographically proximate, not just cached static assets.

The complexity explosion when you move from single-region to multi-region is real: you're now dealing with data consistency across continents, API routing decisions based on geography, state synchronization with cross-Atlantic latency, and failure domains that can isolate entire user populations.

This deep dive examines how production systems architect multi-region frontends: from the network topology that routes users to the nearest region, to the data replication strategies that keep user state consistent, to the operational patterns that make global deployments manageable.


Scale Context

We're architecting for a global application with these characteristics:

MetricValue
Daily Active Users50M+
Geographic DistributionAmericas 40%, EMEA 35%, APAC 25%
Regions Deployed5 (US-East, US-West, EU-West, APAC-East, APAC-South)
Target Latency (P95)<150ms to nearest region
Cross-Region Latency80-250ms (depending on regions)
SLA Target99.95% (26 min downtime/month)
RTO (Recovery Time Objective)<5 minutes
RPO (Recovery Point Objective)<30 seconds
Requests per Second (global)500K+
Data Sync FrequencyReal-time (streaming) + batch reconciliation

At this scale, regional failures aren't hypothetical—they're expected events that happen multiple times per year.


High-Level Architecture

┌─────────────────────────────────────────────────────────────────────────────┐
│                    MULTI-REGION FRONTEND ARCHITECTURE                        │
│                                                                              │
│  ┌─────────────────────────────────────────────────────────────────────┐    │
│  │                     GLOBAL TRAFFIC MANAGEMENT                        │    │
│  │                                                                      │    │
│  │  ┌─────────────────────────────────────────────────────────────┐    │    │
│  │  │                      DNS LAYER                               │    │    │
│  │  │  • GeoDNS (Route53, Cloudflare DNS, NS1)                    │    │    │
│  │  │  • Latency-based routing                                     │    │    │
│  │  │  • Health-check integration                                  │    │    │
│  │  └─────────────────────────────────────────────────────────────┘    │    │
│  │                              │                                       │    │
│  │                              ▼                                       │    │
│  │  ┌─────────────────────────────────────────────────────────────┐    │    │
│  │  │                    GLOBAL LOAD BALANCER                      │    │    │
│  │  │  • Anycast endpoints                                         │    │    │
│  │  │  • Cross-region failover                                     │    │    │
│  │  │  • Request routing policies                                  │    │    │
│  │  └─────────────────────────────────────────────────────────────┘    │    │
│  │                              │                                       │    │
│  └─────────────────────────────────────────────────────────────────────┘    │
│                                 │                                            │
│           ┌─────────────────────┼─────────────────────┐                     │
│           │                     │                     │                     │
│           ▼                     ▼                     ▼                     │
│  ┌─────────────────┐   ┌─────────────────┐   ┌─────────────────┐           │
│  │   AMERICAS       │   │   EMEA           │   │   APAC          │           │
│  │                  │   │                  │   │                  │           │
│  │  ┌────────────┐ │   │  ┌────────────┐ │   │  ┌────────────┐ │           │
│  │  │  CDN PoPs  │ │   │  │  CDN PoPs  │ │   │  │  CDN PoPs  │ │           │
│  │  └────────────┘ │   │  └────────────┘ │   │  └────────────┘ │           │
│  │        │        │   │        │        │   │        │        │           │
│  │  ┌────────────┐ │   │  ┌────────────┐ │   │  ┌────────────┐ │           │
│  │  │  Edge      │ │   │  │  Edge      │ │   │  │  Edge      │ │           │
│  │  │  Compute   │ │   │  │  Compute   │ │   │  │  Compute   │ │           │
│  │  └────────────┘ │   │  └────────────┘ │   │  └────────────┘ │           │
│  │        │        │   │        │        │   │        │        │           │
│  │  ┌────────────┐ │   │  ┌────────────┐ │   │  ┌────────────┐ │           │
│  │  │  Regional  │ │   │  │  Regional  │ │   │  │  Regional  │ │           │
│  │  │  Origin    │ │   │  │  Origin    │ │   │  │  Origin    │ │           │
│  │  │  (us-east) │ │   │  │ (eu-west)  │ │   │  │(ap-northeast)│           │
│  │  └────────────┘ │   │  └────────────┘ │   │  └────────────┘ │           │
│  │        │        │   │        │        │   │        │        │           │
│  │  ┌────────────┐ │   │  ┌────────────┐ │   │  ┌────────────┐ │           │
│  │  │  Regional  │ │   │  │  Regional  │ │   │  │  Regional  │ │           │
│  │  │  Database  │◀┼───┼──│  Database  │◀┼───┼──│  Database  │ │           │
│  │  │  (Primary) │─┼───┼─▶│ (Replica)  │─┼───┼─▶│ (Replica)  │ │           │
│  │  └────────────┘ │   │  └────────────┘ │   │  └────────────┘ │           │
│  │                  │   │                  │   │                  │           │
│  └─────────────────┘   └─────────────────┘   └─────────────────┘           │
│                                                                              │
│                     CROSS-REGION DATA SYNC                                  │
│  ┌─────────────────────────────────────────────────────────────────────┐    │
│  │  • Async replication (database level)                                │    │
│  │  • Event streaming (Kafka/Kinesis cross-region)                     │    │
│  │  • Cache invalidation propagation                                    │    │
│  │  • Session state sync (if needed)                                    │    │
│  └─────────────────────────────────────────────────────────────────────┘    │
│                                                                              │
└─────────────────────────────────────────────────────────────────────────────┘

Traffic Routing

GeoDNS Architecture

sequenceDiagram
    participant U as User (Tokyo)
    participant R as Local Resolver
    participant A as Authoritative DNS
    participant E as Edge (Tokyo)
    participant O as Origin (Singapore)

    U->>R: DNS Query: app.example.com
    R->>A: Recursive query (EDNS Client Subnet: 203.0.113.0/24)

    Note over A: GeoDNS Logic:<br/>1. GeoIP lookup → Tokyo, Japan<br/>2. Health check: APAC region healthy<br/>3. Return APAC endpoints

    A->>R: A: 198.51.100.10 (APAC), TTL: 60
    R->>U: A: 198.51.100.10

    U->>E: HTTPS Request
    E->>O: Forward to regional origin
    O->>E: Response
    E->>U: Response

GeoDNS Configuration:

// DNS routing configuration (conceptual)

interface DNSRoutingConfig {
  zones: {
    name: string;
    regions: RegionConfig[];
  }[];
}

const routingConfig: DNSRoutingConfig = {
  zones: [
    {
      name: 'app.example.com',
      regions: [
        {
          id: 'americas',
          geoTargets: ['NA', 'SA'], // Continents
          endpoints: [
            { ip: '198.51.100.1', weight: 60, location: 'us-east-1' },
            { ip: '198.51.100.2', weight: 40, location: 'us-west-2' }
          ],
          healthCheck: {
            path: '/health',
            interval: 10,
            threshold: 3
          },
          fallback: 'emea' // If all Americas endpoints fail
        },
        {
          id: 'emea',
          geoTargets: ['EU', 'AF', 'ME'],
          endpoints: [
            { ip: '203.0.113.1', weight: 80, location: 'eu-west-1' },
            { ip: '203.0.113.2', weight: 20, location: 'eu-central-1' }
          ],
          healthCheck: { /* ... */ },
          fallback: 'americas'
        },
        {
          id: 'apac',
          geoTargets: ['AS', 'OC'],
          endpoints: [
            { ip: '192.0.2.1', weight: 50, location: 'ap-northeast-1' },
            { ip: '192.0.2.2', weight: 50, location: 'ap-southeast-1' }
          ],
          healthCheck: { /* ... */ },
          fallback: 'emea'
        }
      ]
    }
  ]
};

Latency-Based Routing

GeoDNS routes based on geographic proximity, but network proximity doesn't always equal latency proximity. Latency-based routing measures actual RTT.

┌─────────────────────────────────────────────────────────────────────────────┐
│                    LATENCY-BASED ROUTING                                     │
│                                                                              │
│  Problem with GeoDNS alone:                                                  │
│                                                                              │
│  User in Singapore:                                                          │
│  • GeoDNS says: Route to APAC (Tokyo) - 1500km                              │
│  • But: Singapore-Sydney fiber is faster than Singapore-Tokyo               │
│  • Actual latency: Tokyo 80ms, Sydney 45ms                                  │
│                                                                              │
│  ┌─────────────────────────────────────────────────────────────────────┐    │
│  │                 MEASUREMENT INFRASTRUCTURE                           │    │
│  │                                                                      │    │
│  │  Global Probes:                                                      │    │
│  │  • Deploy measurement agents in each region                         │    │
│  │  • Continuously measure RTT between all region pairs                │    │
│  │  • Feed latency data to DNS routing system                          │    │
│  │                                                                      │    │
│  │  Client-Side Measurement:                                            │    │
│  │  • JavaScript beacon measures latency to multiple regions           │    │
│  │  • Report back to routing system                                    │    │
│  │  • Personalize routing based on actual client latency               │    │
│  │                                                                      │    │
│  └─────────────────────────────────────────────────────────────────────┘    │
│                                                                              │
│  Latency Matrix (measured P50 RTT):                                         │
│                                                                              │
│  From \ To    │ US-East │ US-West │ EU-West │ Tokyo  │ Sydney │            │
│  ─────────────┼─────────┼─────────┼─────────┼────────┼────────┤            │
│  US-East      │    -    │  65ms   │  85ms   │ 160ms  │ 200ms  │            │
│  US-West      │  65ms   │    -    │ 140ms   │ 110ms  │ 150ms  │            │
│  EU-West      │  85ms   │ 140ms   │    -    │ 230ms  │ 280ms  │            │
│  Tokyo        │ 160ms   │ 110ms   │ 230ms   │   -    │ 120ms  │            │
│  Sydney       │ 200ms   │ 150ms   │ 280ms   │ 120ms  │   -    │            │
│                                                                              │
└─────────────────────────────────────────────────────────────────────────────┘

Global Load Balancer Patterns

// Global load balancer decision flow

interface LoadBalancerConfig {
  defaultRegion: string;
  regions: Map<string, RegionEndpoint[]>;
  routingPolicy: 'geo' | 'latency' | 'weighted' | 'failover';
  healthCheckConfig: HealthCheckConfig;
}

class GlobalLoadBalancer {
  async routeRequest(request: Request): Promise<Response> {
    const clientLocation = this.getClientLocation(request);
    const healthyRegions = await this.getHealthyRegions();

    if (healthyRegions.length === 0) {
      return this.handleGlobalOutage(request);
    }

    // Primary routing decision
    let targetRegion = this.selectRegion(clientLocation, healthyRegions);

    // Check region-specific health
    if (!this.isRegionHealthy(targetRegion)) {
      targetRegion = this.selectFallbackRegion(clientLocation, healthyRegions);
    }

    // Route to selected region
    return this.forwardToRegion(request, targetRegion);
  }

  private selectRegion(
    clientLocation: GeoLocation,
    healthyRegions: string[]
  ): string {
    switch (this.config.routingPolicy) {
      case 'geo':
        return this.findNearestRegion(clientLocation, healthyRegions);

      case 'latency':
        return this.findLowestLatencyRegion(clientLocation, healthyRegions);

      case 'weighted':
        return this.selectWeightedRegion(healthyRegions);

      case 'failover':
        return this.selectPrimaryOrFailover(healthyRegions);
    }
  }

  private async forwardToRegion(
    request: Request,
    region: string
  ): Promise<Response> {
    const endpoint = this.getRegionEndpoint(region);

    // Add routing metadata headers
    const headers = new Headers(request.headers);
    headers.set('X-Routed-Region', region);
    headers.set('X-Original-Client-IP', request.headers.get('CF-Connecting-IP') || '');

    const response = await fetch(endpoint, {
      method: request.method,
      headers,
      body: request.body
    });

    // Add debug headers to response
    const responseHeaders = new Headers(response.headers);
    responseHeaders.set('X-Served-By-Region', region);

    return new Response(response.body, {
      status: response.status,
      headers: responseHeaders
    });
  }
}

Regional Origin Architecture

Frontend Server Deployment

Each region runs identical frontend infrastructure:

┌─────────────────────────────────────────────────────────────────────────────┐
│                    REGIONAL FRONTEND STACK                                   │
│                         (per region)                                         │
│                                                                              │
│  ┌─────────────────────────────────────────────────────────────────────┐    │
│  │                    CONTAINER ORCHESTRATION                           │    │
│  │                    (Kubernetes / ECS)                                │    │
│  │                                                                      │    │
│  │  ┌─────────────────────────────────────────────────────────────┐    │    │
│  │  │  Frontend Service (Next.js/Remix/etc)                        │    │    │
│  │  │                                                              │    │    │
│  │  │  Replicas: 10-50 (auto-scaled)                              │    │    │
│  │  │  Resources:                                                  │    │    │
│  │  │    CPU: 500m-2000m                                          │    │    │
│  │  │    Memory: 512Mi-2Gi                                        │    │    │
│  │  │  Health: /health (liveness), /ready (readiness)             │    │    │
│  │  │                                                              │    │    │
│  │  │  ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐       │    │    │
│  │  │  │  Pod 1   │ │  Pod 2   │ │  Pod 3   │ │  Pod N   │       │    │    │
│  │  │  │          │ │          │ │          │ │          │       │    │    │
│  │  │  │ Next.js  │ │ Next.js  │ │ Next.js  │ │ Next.js  │       │    │    │
│  │  │  │ Server   │ │ Server   │ │ Server   │ │ Server   │       │    │    │
│  │  │  │          │ │          │ │          │ │          │       │    │    │
│  │  │  └──────────┘ └──────────┘ └──────────┘ └──────────┘       │    │    │
│  │  │                                                              │    │    │
│  │  └─────────────────────────────────────────────────────────────┘    │    │
│  │                              │                                       │    │
│  │                              ▼                                       │    │
│  │  ┌─────────────────────────────────────────────────────────────┐    │    │
│  │  │                    REGIONAL SERVICES                         │    │    │
│  │  │                                                              │    │    │
│  │  │  ┌────────────────┐  ┌────────────────┐                     │    │    │
│  │  │  │  Redis Cluster │  │  Regional API  │                     │    │    │
│  │  │  │  (Session/     │  │  Gateway       │                     │    │    │
│  │  │  │   Cache)       │  │                │                     │    │    │
│  │  │  └────────────────┘  └────────────────┘                     │    │    │
│  │  │                                                              │    │    │
│  │  │  ┌────────────────┐  ┌────────────────┐                     │    │    │
│  │  │  │  Regional DB   │  │  Object Store  │                     │    │    │
│  │  │  │  (Read Replica │  │  (S3/GCS)      │                     │    │    │
│  │  │  │   + Local)     │  │                │                     │    │    │
│  │  │  └────────────────┘  └────────────────┘                     │    │    │
│  │  │                                                              │    │    │
│  │  └─────────────────────────────────────────────────────────────┘    │    │
│  │                                                                      │    │
│  └─────────────────────────────────────────────────────────────────────┘    │
│                                                                              │
└─────────────────────────────────────────────────────────────────────────────┘

SSR Configuration for Multi-Region

// next.config.js - Multi-region aware configuration

const REGION = process.env.DEPLOY_REGION || 'us-east-1';
const REGIONS = ['us-east-1', 'us-west-2', 'eu-west-1', 'ap-northeast-1'];

const regionConfig = {
  'us-east-1': {
    apiEndpoint: 'https://api.us-east.example.com',
    cacheRedis: 'redis://cache.us-east.internal:6379',
    dbReadReplica: 'postgres://db.us-east.internal:5432/app'
  },
  'eu-west-1': {
    apiEndpoint: 'https://api.eu-west.example.com',
    cacheRedis: 'redis://cache.eu-west.internal:6379',
    dbReadReplica: 'postgres://db.eu-west.internal:5432/app'
  },
  // ... other regions
};

module.exports = {
  env: {
    REGION,
    API_ENDPOINT: regionConfig[REGION].apiEndpoint,
    CACHE_REDIS: regionConfig[REGION].cacheRedis,
  },

  // Different revalidation settings per region based on data freshness needs
  async headers() {
    return [
      {
        source: '/:path*',
        headers: [
          { key: 'X-Served-Region', value: REGION },
          { key: 'X-Region-Timestamp', value: new Date().toISOString() }
        ]
      }
    ];
  },

  // Ensure ISR revalidation accounts for cross-region consistency
  async rewrites() {
    return {
      beforeFiles: [
        // Route API calls to regional endpoint
        {
          source: '/api/:path*',
          destination: `${regionConfig[REGION].apiEndpoint}/:path*`
        }
      ]
    };
  }
};

Data Consistency Across Regions

The CAP Theorem Reality

┌─────────────────────────────────────────────────────────────────────────────┐
│                    CAP THEOREM IN MULTI-REGION                               │
│                                                                              │
│  You can only have 2 of 3:                                                   │
│                                                                              │
│       Consistency ─────────────┬───────────── Availability                  │
│              │                 │                    │                        │
│              │     ┌───────────┴───────────┐       │                        │
│              │     │   Partition           │       │                        │
│              │     │   Tolerance           │       │                        │
│              │     │   (Network splits)    │       │                        │
│              │     └───────────────────────┘       │                        │
│              │                                      │                        │
│              ▼                                      ▼                        │
│                                                                              │
│  In multi-region: Partition tolerance is MANDATORY                          │
│  (networks between regions fail regularly)                                   │
│                                                                              │
│  So you choose between:                                                      │
│                                                                              │
│  ┌────────────────────────────────┬────────────────────────────────┐        │
│  │  CP: Consistency + Partition   │  AP: Availability + Partition  │        │
│  │                                │                                 │        │
│  │  • Strong consistency         │  • Eventually consistent        │        │
│  │  • May reject writes/reads    │  • Always available             │        │
│  │    during partition           │  • May return stale data        │        │
│  │                                │                                 │        │
│  │  Use for:                     │  Use for:                       │        │
│  │  • Financial transactions     │  • Read-heavy workloads         │        │
│  │  • Inventory counts           │  • User preferences             │        │
│  │  • Order processing           │  • Content delivery             │        │
│  │                                │  • Session data (with care)    │        │
│  │                                │                                 │        │
│  └────────────────────────────────┴────────────────────────────────┘        │
│                                                                              │
│  Reality: Most systems use AP for reads, CP for critical writes             │
│                                                                              │
└─────────────────────────────────────────────────────────────────────────────┘

Replication Strategies

// Multi-region data architecture patterns

interface DataReplicationStrategy {
  type: 'single-primary' | 'multi-primary' | 'active-active';
  consistency: 'strong' | 'eventual' | 'causal';
  conflictResolution?: 'last-write-wins' | 'custom-merge' | 'manual';
}

// Pattern 1: Single Primary (Simplest)
const singlePrimary: DataReplicationStrategy = {
  type: 'single-primary',
  consistency: 'eventual',
  // All writes go to primary (us-east-1)
  // Async replication to read replicas
  // Conflict-free (only one writer)
};

// Pattern 2: Regional Primaries (Per-user sharding)
const regionalPrimary = {
  type: 'multi-primary',
  consistency: 'strong', // Within region
  shardingKey: 'user_home_region',
  // User data lives in their home region
  // Cross-region reads hit local replica (eventual)
  // Cross-region writes route to home region
};

// Pattern 3: Active-Active (Most complex)
const activeActive: DataReplicationStrategy = {
  type: 'active-active',
  consistency: 'eventual',
  conflictResolution: 'last-write-wins', // Or custom CRDT
  // Any region can write
  // Must handle conflicts
  // Typically uses CRDTs or operational transforms
};

Database Replication Topology:

┌─────────────────────────────────────────────────────────────────────────────┐
│                SINGLE-PRIMARY REPLICATION                                    │
│                                                                              │
│                    ┌──────────────────┐                                     │
│                    │   US-EAST        │                                     │
│                    │   (Primary)      │                                     │
│                    │                  │                                     │
│                    │   All writes     │                                     │
│                    │   go here        │                                     │
│                    └────────┬─────────┘                                     │
│                             │                                                │
│                    Async Replication                                         │
│                    (typically <1s lag)                                       │
│                             │                                                │
│            ┌────────────────┼────────────────┐                              │
│            │                │                │                              │
│            ▼                ▼                ▼                              │
│   ┌──────────────┐ ┌──────────────┐ ┌──────────────┐                       │
│   │   US-WEST    │ │   EU-WEST    │ │   APAC       │                       │
│   │   (Replica)  │ │   (Replica)  │ │   (Replica)  │                       │
│   │              │ │              │ │              │                       │
│   │   Reads OK   │ │   Reads OK   │ │   Reads OK   │                       │
│   │   Writes ──▶ │ │   Writes ──▶ │ │   Writes ──▶ │                       │
│   │   primary    │ │   primary    │ │   primary    │                       │
│   └──────────────┘ └──────────────┘ └──────────────┘                       │
│                                                                              │
│   Pros:                                                                      │
│   • Simple conflict resolution (none needed)                                │
│   • Strong consistency for writes                                           │
│   • Easy to reason about                                                    │
│                                                                              │
│   Cons:                                                                      │
│   • Write latency for non-primary regions (cross-region RTT)               │
│   • Primary is SPOF for writes                                              │
│   • Failover complexity                                                      │
│                                                                              │
└─────────────────────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────────────────────┐
│                ACTIVE-ACTIVE REPLICATION                                     │
│                                                                              │
│   ┌──────────────┐        ┌──────────────┐        ┌──────────────┐         │
│   │   US-EAST    │◀──────▶│   EU-WEST    │◀──────▶│   APAC       │         │
│   │   (Primary)  │        │   (Primary)  │        │   (Primary)  │         │
│   │              │        │              │        │              │         │
│   │  Read/Write  │        │  Read/Write  │        │  Read/Write  │         │
│   └──────────────┘        └──────────────┘        └──────────────┘         │
│          ▲                       ▲                       ▲                  │
│          │                       │                       │                  │
│          └───────────────────────┼───────────────────────┘                  │
│                                  │                                          │
│                    Bi-directional replication                               │
│                    with conflict resolution                                  │
│                                                                              │
│   Conflict Example:                                                          │
│   T=0: User updates profile in US-EAST: name="Alice"                        │
│   T=0: Same user updates in EU-WEST: name="Alicia"                          │
│   T=1: Replication delivers both updates to all regions                     │
│   T=1: Conflict! Which value wins?                                          │
│                                                                              │
│   Resolution Strategies:                                                     │
│   1. Last-Write-Wins (LWW): Use timestamp, higher wins                     │
│   2. Region Priority: US-EAST always wins conflicts                        │
│   3. Custom Merge: Application-specific logic                              │
│   4. CRDTs: Data structures that merge automatically                       │
│                                                                              │
└─────────────────────────────────────────────────────────────────────────────┘

Session State Across Regions

// Session handling in multi-region

interface SessionStrategy {
  storage: 'regional' | 'global' | 'stateless';
  affinity: 'none' | 'soft' | 'hard';
}

// Strategy 1: Stateless Sessions (JWT)
// Preferred for multi-region
class StatelessSessionManager {
  createSession(user: User): string {
    const payload = {
      userId: user.id,
      email: user.email,
      permissions: user.permissions,
      region: process.env.REGION,
      iat: Date.now(),
      exp: Date.now() + 24 * 60 * 60 * 1000 // 24 hours
    };

    return jwt.sign(payload, process.env.JWT_SECRET);
  }

  validateSession(token: string): SessionData | null {
    try {
      const payload = jwt.verify(token, process.env.JWT_SECRET);
      return payload as SessionData;
    } catch {
      return null;
    }
  }

  // No cross-region sync needed!
  // Token is self-contained
}

// Strategy 2: Regional Sessions with Soft Affinity
// For session-heavy applications
class RegionalSessionManager {
  private redis: Redis;

  async createSession(user: User): Promise<string> {
    const sessionId = crypto.randomUUID();
    const sessionData = {
      userId: user.id,
      createdAt: Date.now(),
      region: process.env.REGION
    };

    // Store in regional Redis
    await this.redis.setex(
      `session:${sessionId}`,
      86400,
      JSON.stringify(sessionData)
    );

    return sessionId;
  }

  async getSession(sessionId: string): Promise<SessionData | null> {
    // Try local region first
    let data = await this.redis.get(`session:${sessionId}`);

    if (!data) {
      // Session might be in another region
      // Option 1: Redirect user to home region
      // Option 2: Fetch from global session store
      data = await this.fetchFromGlobalStore(sessionId);
    }

    return data ? JSON.parse(data) : null;
  }

  // Cross-region session migration
  async migrateSession(sessionId: string, targetRegion: string): Promise<void> {
    const data = await this.redis.get(`session:${sessionId}`);
    if (data) {
      // Publish to cross-region message queue
      await this.eventBus.publish('session.migrate', {
        sessionId,
        targetRegion,
        data
      });
    }
  }
}

// Strategy 3: Global Session Store
// Highest consistency, highest latency
class GlobalSessionManager {
  private globalRedis: Redis; // Redis with cross-region replication

  async createSession(user: User): Promise<string> {
    const sessionId = crypto.randomUUID();

    // Write to global store (higher latency)
    await this.globalRedis.setex(
      `session:${sessionId}`,
      86400,
      JSON.stringify({ userId: user.id, /* ... */ })
    );

    return sessionId;
  }

  async getSession(sessionId: string): Promise<SessionData | null> {
    // May read from local replica (eventually consistent)
    // Or from primary (strongly consistent but slower)
    const data = await this.globalRedis.get(`session:${sessionId}`);
    return data ? JSON.parse(data) : null;
  }
}

API Routing Architecture

BFF Per Region

┌─────────────────────────────────────────────────────────────────────────────┐
│                    REGIONAL BFF ARCHITECTURE                                 │
│                                                                              │
│  User Request ──▶ CDN/Edge ──▶ Regional BFF ──▶ Backend Services           │
│                                                                              │
│  ┌─────────────────────────────────────────────────────────────────────┐    │
│  │                      US-EAST REGION                                  │    │
│  │                                                                      │    │
│  │  ┌──────────────────────────────────────────────────────────────┐   │    │
│  │  │                   BFF (Backend for Frontend)                  │   │    │
│  │  │                                                               │   │    │
│  │  │  Responsibilities:                                            │   │    │
│  │  │  • Aggregate multiple backend calls                          │   │    │
│  │  │  • Transform data for frontend consumption                   │   │    │
│  │  │  • Handle authentication                                      │   │    │
│  │  │  • Cache responses regionally                                │   │    │
│  │  │  • Route requests to correct backend                         │   │    │
│  │  │                                                               │   │    │
│  │  │  ┌─────────┐  ┌─────────┐  ┌─────────┐  ┌─────────┐         │   │    │
│  │  │  │ User    │  │ Product │  │ Cart    │  │ Search  │         │   │    │
│  │  │  │ Service │  │ Service │  │ Service │  │ Service │         │   │    │
│  │  │  └────┬────┘  └────┬────┘  └────┬────┘  └────┬────┘         │   │    │
│  │  │       │            │            │            │                │   │    │
│  │  └───────┼────────────┼────────────┼────────────┼────────────────┘   │    │
│  │          │            │            │            │                    │    │
│  │          ▼            ▼            ▼            ▼                    │    │
│  │  ┌─────────────────────────────────────────────────────────────┐    │    │
│  │  │               REGIONAL DATA LAYER                            │    │    │
│  │  │                                                              │    │    │
│  │  │  [User DB]  [Product DB]  [Cart Redis]  [Search Index]      │    │    │
│  │  │  (replica)   (replica)    (primary)     (replica)           │    │    │
│  │  │                                                              │    │    │
│  │  └─────────────────────────────────────────────────────────────┘    │    │
│  │                                                                      │    │
│  └─────────────────────────────────────────────────────────────────────┘    │
│                                                                              │
│  Cross-Region Communication:                                                 │
│                                                                              │
│  • Cart writes may need to go to "home region" for consistency             │
│  • Search might hit global index for comprehensive results                  │
│  • User writes route to primary DB region                                   │
│                                                                              │
└─────────────────────────────────────────────────────────────────────────────┘

Request Routing Logic

// BFF routing logic

interface RouteConfig {
  localFirst: boolean;
  crossRegionFallback: boolean;
  consistencyRequirement: 'strong' | 'eventual';
}

class RegionalBFF {
  private region = process.env.REGION;
  private services: Map<string, ServiceConfig>;

  async handleRequest(
    endpoint: string,
    method: string,
    data?: unknown
  ): Promise<Response> {
    const config = this.getRouteConfig(endpoint);

    // Determine target region
    const targetRegion = this.determineTargetRegion(endpoint, method, config);

    if (targetRegion === this.region) {
      return this.callLocalService(endpoint, method, data);
    } else {
      return this.callRemoteRegion(endpoint, method, data, targetRegion);
    }
  }

  private determineTargetRegion(
    endpoint: string,
    method: string,
    config: RouteConfig
  ): string {
    // Reads: prefer local region (eventual consistency OK)
    if (method === 'GET' && config.consistencyRequirement === 'eventual') {
      return this.region;
    }

    // Writes: may need to go to primary region
    if (['POST', 'PUT', 'DELETE'].includes(method)) {
      const dataOwnerRegion = this.getDataOwnerRegion(endpoint);

      if (config.consistencyRequirement === 'strong') {
        return dataOwnerRegion;
      }

      // For eventual consistency writes, write locally
      // and async replicate
      return this.region;
    }

    return this.region;
  }

  private async callRemoteRegion(
    endpoint: string,
    method: string,
    data: unknown,
    targetRegion: string
  ): Promise<Response> {
    const regionEndpoint = this.getRegionEndpoint(targetRegion);

    try {
      const response = await fetch(`${regionEndpoint}${endpoint}`, {
        method,
        headers: {
          'Content-Type': 'application/json',
          'X-Forwarded-From-Region': this.region,
          'X-Request-Id': crypto.randomUUID()
        },
        body: data ? JSON.stringify(data) : undefined,
        // Cross-region timeout
        signal: AbortSignal.timeout(5000)
      });

      return response;
    } catch (error) {
      // Handle cross-region failure
      if (this.config.crossRegionFallback) {
        return this.handleCrossRegionFailure(endpoint, method, data);
      }
      throw error;
    }
  }

  private async handleCrossRegionFailure(
    endpoint: string,
    method: string,
    data: unknown
  ): Promise<Response> {
    // Options:
    // 1. Queue request for retry when region recovers
    // 2. Serve stale data for reads
    // 3. Accept write locally and reconcile later

    if (method === 'GET') {
      // Try to serve from local cache
      const cached = await this.localCache.get(endpoint);
      if (cached) {
        return new Response(cached, {
          headers: { 'X-Cache-Status': 'stale-fallback' }
        });
      }
    }

    // Queue for later
    await this.retryQueue.enqueue({
      endpoint,
      method,
      data,
      targetRegion: this.getPrimaryRegion(),
      originalTimestamp: Date.now()
    });

    return new Response(
      JSON.stringify({ queued: true, message: 'Request queued for processing' }),
      { status: 202 }
    );
  }
}

Asset Delivery Strategy

Multi-Region Asset Pipeline

┌─────────────────────────────────────────────────────────────────────────────┐
│                    ASSET DEPLOYMENT PIPELINE                                 │
│                                                                              │
│  Build System (CI/CD)                                                        │
│        │                                                                     │
│        ▼                                                                     │
│  ┌─────────────────────────────────────────────────────────────────────┐    │
│  │                    BUILD ARTIFACTS                                   │    │
│  │                                                                      │    │
│  │  • JavaScript bundles (content-hashed)                              │    │
│  │  • CSS files (content-hashed)                                       │    │
│  │  • Static images (optimized, multiple formats)                      │    │
│  │  • Fonts                                                            │    │
│  │  • Source maps                                                      │    │
│  │                                                                      │    │
│  └─────────────────────────────────────────────────────────────────────┘    │
│        │                                                                     │
│        ▼                                                                     │
│  ┌─────────────────────────────────────────────────────────────────────┐    │
│  │                    UPLOAD TO ALL REGIONS                             │    │
│  │                                                                      │    │
│  │  Parallel upload to regional object stores:                         │    │
│  │                                                                      │    │
│  │  ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐   │    │
│  │  │ S3          │ │ S3          │ │ S3          │ │ S3          │   │    │
│  │  │ us-east-1   │ │ eu-west-1   │ │ ap-northeast│ │ ap-southeast│   │    │
│  │  └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘   │    │
│  │                                                                      │    │
│  │  OR: Single bucket with cross-region replication                    │    │
│  │                                                                      │    │
│  │  ┌────────────────────────────────────────────────────────────────┐ │    │
│  │  │  S3 us-east-1 (primary) ────replication────▶ Other regions    │ │    │
│  │  └────────────────────────────────────────────────────────────────┘ │    │
│  │                                                                      │    │
│  └─────────────────────────────────────────────────────────────────────┘    │
│        │                                                                     │
│        ▼                                                                     │
│  ┌─────────────────────────────────────────────────────────────────────┐    │
│  │                    CDN CONFIGURATION                                 │    │
│  │                                                                      │    │
│  │  • Origin groups with regional failover                             │    │
│  │  • Cache-Control: public, max-age=31536000, immutable              │    │
│  │  • Aggressive edge caching                                          │    │
│  │                                                                      │    │
│  └─────────────────────────────────────────────────────────────────────┘    │
│                                                                              │
└─────────────────────────────────────────────────────────────────────────────┘

Atomic Deployments Across Regions

// Deployment coordination service

interface DeploymentConfig {
  version: string;
  regions: string[];
  rolloutStrategy: 'all-at-once' | 'rolling' | 'canary';
  healthCheckTimeout: number;
}

class MultiRegionDeployer {
  async deploy(config: DeploymentConfig): Promise<DeploymentResult> {
    const { version, regions, rolloutStrategy } = config;

    switch (rolloutStrategy) {
      case 'all-at-once':
        return this.deployAllAtOnce(version, regions);

      case 'rolling':
        return this.deployRolling(version, regions);

      case 'canary':
        return this.deployCanary(version, regions);
    }
  }

  private async deployAllAtOnce(
    version: string,
    regions: string[]
  ): Promise<DeploymentResult> {
    // Upload assets to all regions in parallel
    await Promise.all(
      regions.map(region => this.uploadAssets(version, region))
    );

    // Atomic switch: Update all regions simultaneously
    const switchPromises = regions.map(async region => {
      await this.updateVersionPointer(version, region);
      await this.purgeEdgeCache(region);
    });

    const results = await Promise.allSettled(switchPromises);

    // Verify all regions healthy
    const healthChecks = await Promise.all(
      regions.map(region => this.healthCheck(region))
    );

    if (healthChecks.some(h => !h.healthy)) {
      // Rollback all regions
      await this.rollbackAll(regions);
      throw new Error('Deployment failed health checks');
    }

    return { success: true, version, regions };
  }

  private async deployRolling(
    version: string,
    regions: string[]
  ): Promise<DeploymentResult> {
    const deployed: string[] = [];

    for (const region of regions) {
      try {
        await this.uploadAssets(version, region);
        await this.updateVersionPointer(version, region);
        await this.purgeEdgeCache(region);

        // Health check before proceeding
        const health = await this.healthCheckWithRetry(region, 3);
        if (!health.healthy) {
          throw new Error(`Health check failed in ${region}`);
        }

        deployed.push(region);

        // Bake time between regions
        await this.sleep(30000); // 30 seconds
      } catch (error) {
        // Rollback deployed regions
        await this.rollbackRegions(deployed, version);
        throw error;
      }
    }

    return { success: true, version, regions };
  }

  private async deployCanary(
    version: string,
    regions: string[]
  ): Promise<DeploymentResult> {
    // Pick canary region (usually smallest or most resilient)
    const canaryRegion = this.selectCanaryRegion(regions);
    const remainingRegions = regions.filter(r => r !== canaryRegion);

    // Deploy to canary first
    await this.uploadAssets(version, canaryRegion);
    await this.updateVersionPointer(version, canaryRegion);
    await this.purgeEdgeCache(canaryRegion);

    // Monitor canary for extended period
    const canaryDuration = 300000; // 5 minutes
    const canaryResult = await this.monitorCanary(canaryRegion, canaryDuration);

    if (!canaryResult.success) {
      await this.rollbackRegion(canaryRegion);
      throw new Error(`Canary failed: ${canaryResult.error}`);
    }

    // Proceed with remaining regions
    return this.deployAllAtOnce(version, remainingRegions);
  }

  private async monitorCanary(
    region: string,
    duration: number
  ): Promise<{ success: boolean; error?: string }> {
    const startTime = Date.now();
    const metrics: CanaryMetric[] = [];

    while (Date.now() - startTime < duration) {
      const currentMetrics = await this.getRegionMetrics(region);
      metrics.push(currentMetrics);

      // Check for anomalies
      if (this.detectAnomaly(metrics)) {
        return {
          success: false,
          error: 'Error rate anomaly detected'
        };
      }

      await this.sleep(10000); // Check every 10 seconds
    }

    return { success: true };
  }
}

Failure Modes and Resilience

Regional Failure Handling

┌─────────────────────────────────────────────────────────────────────────────┐
│                    REGIONAL FAILURE SCENARIOS                                │
│                                                                              │
│  ┌─────────────────────────────────────────────────────────────────────┐    │
│  │  SCENARIO 1: Complete Region Outage                                  │    │
│  │                                                                      │    │
│  │  Cause: AWS us-east-1 goes down, data center fire, network partition│    │
│  │                                                                      │    │
│  │  Detection:                                                          │    │
│  │  • Health checks fail for >30 seconds                               │    │
│  │  • Multiple probes from different locations confirm                 │    │
│  │  • AWS/GCP health dashboard (for cloud issues)                      │    │
│  │                                                                      │    │
│  │  Response:                                                           │    │
│  │  1. DNS/GLB automatically routes traffic to other regions           │    │
│  │  2. Alert on-call team                                              │    │
│  │  3. If primary DB region, initiate failover                         │    │
│  │  4. Scale up receiving regions                                      │    │
│  │                                                                      │    │
│  │  ┌────────────────────────────────────────────────────────────────┐ │    │
│  │  │  Before:  US-EAST: 40%  │  EU-WEST: 35%  │  APAC: 25%         │ │    │
│  │  │  After:   US-EAST:  X   │  EU-WEST: 55%  │  APAC: 45%         │ │    │
│  │  └────────────────────────────────────────────────────────────────┘ │    │
│  │                                                                      │    │
│  └─────────────────────────────────────────────────────────────────────┘    │
│                                                                              │
│  ┌─────────────────────────────────────────────────────────────────────┐    │
│  │  SCENARIO 2: Partial Degradation                                     │    │
│  │                                                                      │    │
│  │  Cause: High error rate, elevated latency, capacity issues          │    │
│  │                                                                      │    │
│  │  Detection:                                                          │    │
│  │  • Error rate > 5% threshold                                        │    │
│  │  • P99 latency > 500ms threshold                                    │    │
│  │  • Gradual vs sudden (different responses)                          │    │
│  │                                                                      │    │
│  │  Response (Gradual):                                                 │    │
│  │  1. Reduce traffic weight to affected region                        │    │
│  │  2. Scale up affected region if resource constrained                │    │
│  │  3. Investigate root cause                                          │    │
│  │                                                                      │    │
│  │  Response (Sudden):                                                  │    │
│  │  1. Immediately reduce to 0% traffic                                │    │
│  │  2. Treat as full outage                                            │    │
│  │                                                                      │    │
│  └─────────────────────────────────────────────────────────────────────┘    │
│                                                                              │
│  ┌─────────────────────────────────────────────────────────────────────┐    │
│  │  SCENARIO 3: Cross-Region Network Partition                          │    │
│  │                                                                      │    │
│  │  Cause: Submarine cable cut, BGP issues, cloud interconnect failure │    │
│  │                                                                      │    │
│  │  Impact:                                                             │    │
│  │  • Regions can't communicate                                        │    │
│  │  • Database replication halted                                      │    │
│  │  • Cross-region API calls fail                                      │    │
│  │                                                                      │    │
│  │  Response:                                                           │    │
│  │  1. Each region operates independently (if architected for it)      │    │
│  │  2. Queue cross-region operations for later                         │    │
│  │  3. Serve potentially stale data with warnings                      │    │
│  │  4. Reconcile when partition heals                                  │    │
│  │                                                                      │    │
│  └─────────────────────────────────────────────────────────────────────┘    │
│                                                                              │
└─────────────────────────────────────────────────────────────────────────────┘

Circuit Breaker Implementation

// Cross-region circuit breaker

interface CircuitBreakerConfig {
  failureThreshold: number;     // Failures before open
  successThreshold: number;     // Successes to close
  timeout: number;              // Time before half-open
  volumeThreshold: number;      // Min requests to evaluate
}

enum CircuitState {
  CLOSED = 'closed',
  OPEN = 'open',
  HALF_OPEN = 'half-open'
}

class RegionalCircuitBreaker {
  private state: CircuitState = CircuitState.CLOSED;
  private failures = 0;
  private successes = 0;
  private lastFailureTime = 0;
  private requestCount = 0;

  constructor(
    private region: string,
    private config: CircuitBreakerConfig
  ) {}

  async execute<T>(operation: () => Promise<T>): Promise<T> {
    if (!this.canExecute()) {
      throw new CircuitOpenError(this.region);
    }

    this.requestCount++;

    try {
      const result = await operation();
      this.recordSuccess();
      return result;
    } catch (error) {
      this.recordFailure();
      throw error;
    }
  }

  private canExecute(): boolean {
    if (this.state === CircuitState.CLOSED) {
      return true;
    }

    if (this.state === CircuitState.OPEN) {
      // Check if timeout has elapsed
      if (Date.now() - this.lastFailureTime > this.config.timeout) {
        this.state = CircuitState.HALF_OPEN;
        return true;
      }
      return false;
    }

    // Half-open: allow one request through
    return true;
  }

  private recordSuccess(): void {
    if (this.state === CircuitState.HALF_OPEN) {
      this.successes++;
      if (this.successes >= this.config.successThreshold) {
        this.close();
      }
    }
    this.failures = 0;
  }

  private recordFailure(): void {
    this.failures++;
    this.lastFailureTime = Date.now();

    if (this.state === CircuitState.HALF_OPEN) {
      this.open();
      return;
    }

    if (this.failures >= this.config.failureThreshold &&
        this.requestCount >= this.config.volumeThreshold) {
      this.open();
    }
  }

  private open(): void {
    this.state = CircuitState.OPEN;
    this.successes = 0;
    console.log(`Circuit OPEN for region ${this.region}`);
    this.emitMetric('circuit_breaker_open', { region: this.region });
  }

  private close(): void {
    this.state = CircuitState.CLOSED;
    this.failures = 0;
    this.successes = 0;
    this.requestCount = 0;
    console.log(`Circuit CLOSED for region ${this.region}`);
    this.emitMetric('circuit_breaker_closed', { region: this.region });
  }
}

// Usage in multi-region client
class MultiRegionClient {
  private circuitBreakers = new Map<string, RegionalCircuitBreaker>();

  async fetch(region: string, url: string): Promise<Response> {
    const cb = this.getCircuitBreaker(region);

    try {
      return await cb.execute(async () => {
        const response = await fetch(url, {
          signal: AbortSignal.timeout(5000)
        });

        if (!response.ok) {
          throw new Error(`HTTP ${response.status}`);
        }

        return response;
      });
    } catch (error) {
      if (error instanceof CircuitOpenError) {
        // Fallback to another region
        return this.fallbackFetch(region, url);
      }
      throw error;
    }
  }

  private fallbackFetch(failedRegion: string, url: string): Promise<Response> {
    const fallbackOrder = this.getFallbackOrder(failedRegion);

    for (const region of fallbackOrder) {
      try {
        return this.fetch(region, this.translateUrl(url, region));
      } catch {
        continue;
      }
    }

    throw new Error('All regions unavailable');
  }
}

Observability in Multi-Region

Distributed Tracing Across Regions

// Cross-region trace propagation

interface TraceContext {
  traceId: string;
  spanId: string;
  parentSpanId?: string;
  originRegion: string;
  hops: RegionHop[];
}

interface RegionHop {
  region: string;
  spanId: string;
  timestamp: number;
  latencyMs: number;
}

class MultiRegionTracer {
  createTrace(request: Request): TraceContext {
    // Check for incoming trace context
    const traceparent = request.headers.get('traceparent');

    if (traceparent) {
      return this.parseAndExtend(traceparent, request);
    }

    // New trace
    return {
      traceId: this.generateTraceId(),
      spanId: this.generateSpanId(),
      originRegion: this.currentRegion,
      hops: [{
        region: this.currentRegion,
        spanId: this.generateSpanId(),
        timestamp: Date.now(),
        latencyMs: 0
      }]
    };
  }

  propagateToRegion(
    context: TraceContext,
    targetRegion: string
  ): Headers {
    const newSpanId = this.generateSpanId();
    const headers = new Headers();

    // W3C Trace Context
    headers.set(
      'traceparent',
      `00-${context.traceId}-${newSpanId}-01`
    );

    // Custom context for multi-region
    headers.set(
      'x-multi-region-context',
      JSON.stringify({
        originRegion: context.originRegion,
        hops: [
          ...context.hops,
          {
            region: targetRegion,
            spanId: newSpanId,
            timestamp: Date.now(),
            latencyMs: 0 // Will be calculated on receipt
          }
        ]
      })
    );

    return headers;
  }

  recordRegionHop(
    context: TraceContext,
    fromRegion: string,
    toRegion: string,
    latencyMs: number
  ): void {
    // Send to centralized tracing system
    this.tracingClient.recordSpan({
      traceId: context.traceId,
      spanId: context.spanId,
      name: `cross-region-${fromRegion}-to-${toRegion}`,
      duration: latencyMs,
      tags: {
        'region.from': fromRegion,
        'region.to': toRegion,
        'region.hop_count': context.hops.length
      }
    });
  }
}

Regional Metrics Aggregation

┌─────────────────────────────────────────────────────────────────────────────┐
│                    METRICS AGGREGATION ARCHITECTURE                          │
│                                                                              │
│  ┌─────────────────────────────────────────────────────────────────────┐    │
│  │                    REGIONAL COLLECTION                               │    │
│  │                                                                      │    │
│  │  US-EAST         EU-WEST          APAC                               │    │
│  │  ┌───────┐      ┌───────┐        ┌───────┐                          │    │
│  │  │Metrics│      │Metrics│        │Metrics│                          │    │
│  │  │Agents │      │Agents │        │Agents │                          │    │
│  │  └───┬───┘      └───┬───┘        └───┬───┘                          │    │
│  │      │              │                │                               │    │
│  │      ▼              ▼                ▼                               │    │
│  │  ┌───────┐      ┌───────┐        ┌───────┐                          │    │
│  │  │Regional     │Regional        │Regional                           │    │
│  │  │Prometheus│  │Prometheus│     │Prometheus│                        │    │
│  │  └───┬───┘      └───┬───┘        └───┬───┘                          │    │
│  │      │              │                │                               │    │
│  └──────┼──────────────┼────────────────┼───────────────────────────────┘    │
│         │              │                │                                    │
│         └──────────────┼────────────────┘                                    │
│                        │                                                     │
│                        ▼                                                     │
│  ┌─────────────────────────────────────────────────────────────────────┐    │
│  │                    GLOBAL AGGREGATION                                │    │
│  │                                                                      │    │
│  │  Options:                                                            │    │
│  │                                                                      │    │
│  │  1. Centralized Prometheus + Federation                             │    │
│  │     • Single global view                                            │    │
│  │     • Higher latency for queries                                    │    │
│  │                                                                      │    │
│  │  2. Thanos / Cortex                                                 │    │
│  │     • Long-term storage                                             │    │
│  │     • Global query layer                                            │    │
│  │     • Regional data stays in region                                 │    │
│  │                                                                      │    │
│  │  3. Push to central (Datadog, New Relic, etc.)                     │    │
│  │     • Simplest operationally                                        │    │
│  │     • Vendor lock-in                                                │    │
│  │                                                                      │    │
│  └─────────────────────────────────────────────────────────────────────┘    │
│                                                                              │
│  Key Multi-Region Metrics:                                                   │
│                                                                              │
│  • Cross-region latency (P50, P95, P99)                                    │
│  • Regional error rates                                                      │
│  • Traffic distribution by region                                           │
│  • Database replication lag                                                  │
│  • Regional capacity utilization                                            │
│  • Failover events                                                          │
│                                                                              │
└─────────────────────────────────────────────────────────────────────────────┘

Cost Optimization

Multi-Region Cost Factors

┌─────────────────────────────────────────────────────────────────────────────┐
│                    MULTI-REGION COST BREAKDOWN                               │
│                                                                              │
│  ┌─────────────────────────────────────────────────────────────────────┐    │
│  │  COMPUTE COSTS                                                       │    │
│  │                                                                      │    │
│  │  Single Region:    $50,000/month                                    │    │
│  │  Three Regions:    $150,000/month (3x)                              │    │
│  │  With Auto-scaling: $120,000/month (~2.4x)                          │    │
│  │                                                                      │    │
│  │  Optimization: Right-size non-primary regions during off-peak       │    │
│  │                                                                      │    │
│  └─────────────────────────────────────────────────────────────────────┘    │
│                                                                              │
│  ┌─────────────────────────────────────────────────────────────────────┐    │
│  │  DATA TRANSFER COSTS                                                 │    │
│  │                                                                      │    │
│  │  Cross-region transfer (AWS): $0.02/GB                              │    │
│  │                                                                      │    │
│  │  With 10TB/day replication:                                         │    │
│  │    Daily: 10,000 GB × $0.02 = $200                                  │    │
│  │    Monthly: $6,000                                                   │    │
│  │                                                                      │    │
│  │  Optimization:                                                       │    │
│  │  • Compress replication streams                                     │    │
│  │  • Use VPC peering vs public internet                               │    │
│  │  • Replicate only what's needed                                     │    │
│  │                                                                      │    │
│  └─────────────────────────────────────────────────────────────────────┘    │
│                                                                              │
│  ┌─────────────────────────────────────────────────────────────────────┐    │
│  │  DATABASE COSTS                                                      │    │
│  │                                                                      │    │
│  │  Primary + 2 read replicas (same region): $10,000/month            │    │
│  │  + Cross-region replicas (2 regions): +$20,000/month               │    │
│  │                                                                      │    │
│  │  Total: $30,000/month                                               │    │
│  │                                                                      │    │
│  │  Optimization:                                                       │    │
│  │  • Use smaller instance types in secondary regions                  │    │
│  │  • Consider Aurora Global Database (lower replication cost)         │    │
│  │                                                                      │    │
│  └─────────────────────────────────────────────────────────────────────┘    │
│                                                                              │
│  Total Multi-Region Premium: ~2.5-3x single region                         │
│                                                                              │
│  ROI Calculation:                                                            │
│  • Single region downtime cost: $100,000/hour                              │
│  • Multi-region prevents ~10 hours/year of downtime                         │
│  • Avoided cost: $1,000,000/year                                           │
│  • Multi-region premium: ~$800,000/year                                    │
│  • Net positive if downtime impact is real                                 │
│                                                                              │
└─────────────────────────────────────────────────────────────────────────────┘

Summary

Multi-region frontend delivery is not about replicating your infrastructure—it's about designing a system where users are always close to responsive, healthy compute while maintaining data consistency and operational sanity.

Key Architectural Decisions:

  1. Traffic routing is the foundation - GeoDNS + GLB with health checks. Get this wrong and nothing else matters.

  2. Choose your consistency model explicitly - Most systems need strong consistency for writes, eventual for reads. Document where each applies.

  3. Session state is the sneaky hard problem - Prefer stateless (JWT) unless you have a compelling reason for server-side sessions.

  4. Database architecture drives everything - Single-primary with read replicas is simplest. Active-active requires conflict resolution you'll probably get wrong.

  5. Design for partial failure - Individual regions will fail. Your system should degrade gracefully, not catastrophically.

  6. Deployment must be region-aware - Rolling deployments with health gates. Never deploy to all regions simultaneously without validation.

  7. Observability across regions is mandatory - Distributed tracing, regional metrics, cross-region latency monitoring. You can't fix what you can't see.

  8. Cost scales superlinearly - 3 regions costs ~2.5x, not 3x, but only with careful optimization. Factor this into business decisions.

Multi-region is expensive and complex. Do it when the availability requirements demand it, not as a default. But when you do it, architect it properly from day one—retrofitting multi-region onto a single-region system is far more painful than building it correctly initially.

What did you think?

© 2026 Vidhya Sagar Thakur. All rights reserved.