{
  "docVersion": 1,
  "id": "template-multi-region-active-active",
  "name": "Multi-region active-active",
  "purpose": "Active-active SaaS across two regions: latency-routed traffic, tenant homing for conflict-free writes, async hub-and-spoke replication, witness-region quorum and failover that flips routing rather than enabling cross-region calls.",
  "nodes": {
    "gdns": {
      "type": "dns",
      "label": "Global DNS / anycast",
      "x": 20,
      "y": 300,
      "runtime": "latency-based routing",
      "notes": "Failover lever lives here: re-home tenants by changing answers, not architecture."
    },
    "gwa": {
      "type": "gateway",
      "label": "Gateway",
      "x": 300,
      "y": 90,
      "runtime": "us-east"
    },
    "apia": {
      "type": "k8s",
      "label": "App",
      "x": 550,
      "y": 90,
      "runtime": "serves tenants homed A-M",
      "patterns": [
        "autoscale"
      ]
    },
    "dba": {
      "type": "database",
      "label": "DB (region A)",
      "x": 800,
      "y": 90,
      "runtime": "owner of A-M writes",
      "patterns": [
        "backup"
      ]
    },
    "gwb": {
      "type": "gateway",
      "label": "Gateway",
      "x": 300,
      "y": 420,
      "runtime": "eu-west"
    },
    "apib": {
      "type": "k8s",
      "label": "App",
      "x": 550,
      "y": 420,
      "runtime": "serves tenants homed N-Z",
      "patterns": [
        "autoscale"
      ]
    },
    "dbb": {
      "type": "database",
      "label": "DB (region B)",
      "x": 800,
      "y": 420,
      "runtime": "owner of N-Z writes",
      "patterns": [
        "backup"
      ]
    },
    "bus": {
      "type": "bus",
      "label": "Replication hub",
      "x": 1080,
      "y": 255,
      "runtime": "async · ordered per tenant",
      "color": "purple",
      "notes": "Hub-and-spoke: every region publishes its changes here and consumes everyone else's. Lag is measured and alarmed — it IS your RPO."
    },
    "witness": {
      "type": "region",
      "label": "Witness region",
      "x": 1330,
      "y": 255,
      "runtime": "quorum tiebreaker · no data plane",
      "color": "gray",
      "notes": "Holds membership state only. During a partition, whichever region the witness can see wins the failover vote."
    }
  },
  "edges": {
    "e1": {
      "from": "gdns",
      "to": "gwa",
      "fromSide": "right",
      "toSide": "left",
      "label": "closest region",
      "animated": true
    },
    "e2": {
      "from": "gdns",
      "to": "gwb",
      "fromSide": "right",
      "toSide": "left",
      "animated": true
    },
    "e3": {
      "from": "gwa",
      "to": "apia",
      "fromSide": "right",
      "toSide": "left"
    },
    "e4": {
      "from": "apia",
      "to": "dba",
      "fromSide": "right",
      "toSide": "left",
      "label": "region-local only",
      "patterns": [
        "timeout"
      ]
    },
    "e5": {
      "from": "gwb",
      "to": "apib",
      "fromSide": "right",
      "toSide": "left"
    },
    "e6": {
      "from": "apib",
      "to": "dbb",
      "fromSide": "right",
      "toSide": "left",
      "label": "region-local only"
    },
    "e7": {
      "from": "dba",
      "to": "bus",
      "fromSide": "right",
      "toSide": "left",
      "label": "async replication",
      "style": "dashed",
      "dir": "both",
      "patterns": [
        "ordered",
        "dedup"
      ]
    },
    "e8": {
      "from": "dbb",
      "to": "bus",
      "fromSide": "right",
      "toSide": "left",
      "label": "async replication",
      "style": "dashed",
      "dir": "both",
      "patterns": [
        "ordered",
        "dedup"
      ]
    },
    "e9": {
      "from": "bus",
      "to": "witness",
      "fromSide": "right",
      "toSide": "left",
      "label": "membership · quorum",
      "style": "dashed"
    }
  },
  "boxes": {
    "b1": {
      "x": 270,
      "y": 30,
      "w": 710,
      "h": 210,
      "label": "region A — us-east · fully self-sufficient",
      "color": "blue",
      "opacity": 0.04
    },
    "b2": {
      "x": 270,
      "y": 360,
      "w": 710,
      "h": 210,
      "label": "region B — eu-west · fully self-sufficient",
      "color": "green",
      "opacity": 0.04
    }
  },
  "texts": {
    "t1": {
      "x": 20,
      "y": 480,
      "text": "the golden rule: region B failing must not add\none millisecond to region A. If a request crosses\nregions synchronously, you built one region\nwith extra steps.",
      "color": "amber",
      "size": 12
    }
  },
  "meta": {
    "createdAt": "2026-07-13T09:00:00.000Z",
    "modifiedAt": "2026-07-13T09:00:00.000Z"
  }
}