{
  "docVersion": 1,
  "id": "template-disaster-recovery-tiers",
  "name": "Disaster recovery tiers",
  "purpose": "The same application at three DR postures — pilot light (data only), warm standby (minimal compute) and hot standby (full capacity) — with the RTO/RPO trade each one buys.",
  "nodes": {
    "app": {
      "type": "k8s",
      "label": "Production app",
      "x": 40,
      "y": 90,
      "runtime": "full capacity",
      "color": "green"
    },
    "db": {
      "type": "database",
      "label": "Primary DB",
      "x": 40,
      "y": 300,
      "runtime": "source of truth",
      "color": "green",
      "patterns": [
        "backup"
      ]
    },
    "appp": {
      "type": "server",
      "label": "App (not running)",
      "x": 360,
      "y": 90,
      "runtime": "AMIs + IaC ready",
      "style": "dashed",
      "notes": "Nothing runs here day to day. Recovery = boot everything from templates — that boot time IS the RTO."
    },
    "dbp": {
      "type": "database",
      "label": "Replica",
      "x": 360,
      "y": 300,
      "runtime": "async · minutes behind"
    },
    "appw": {
      "type": "server",
      "label": "App (10% capacity)",
      "x": 680,
      "y": 90,
      "runtime": "always on · scales on failover",
      "patterns": [
        "standby"
      ],
      "notes": "Alive and serving health checks. Failover = scale-up + traffic flip; no cold boots on the critical path."
    },
    "dbw": {
      "type": "database",
      "label": "Replica",
      "x": 680,
      "y": 300,
      "runtime": "async · seconds behind"
    },
    "apph": {
      "type": "k8s",
      "label": "App (full capacity)",
      "x": 1000,
      "y": 90,
      "runtime": "takes traffic in seconds",
      "patterns": [
        "standby",
        "autoscale"
      ]
    },
    "dbh": {
      "type": "database",
      "label": "Replica",
      "x": 1000,
      "y": 300,
      "runtime": "semi-sync · near-zero loss"
    }
  },
  "edges": {
    "e1": {
      "from": "app",
      "to": "db",
      "fromSide": "bottom",
      "toSide": "top",
      "label": "writes",
      "animated": true
    },
    "e2": {
      "from": "db",
      "to": "dbp",
      "fromSide": "right",
      "toSide": "left",
      "label": "async replication",
      "style": "dashed"
    },
    "e3": {
      "from": "db",
      "to": "dbw",
      "fromSide": "bottom",
      "toSide": "bottom",
      "label": "async",
      "style": "dashed"
    },
    "e4": {
      "from": "db",
      "to": "dbh",
      "fromSide": "top",
      "toSide": "top",
      "label": "semi-sync",
      "style": "dashed",
      "patterns": [
        "ordered"
      ]
    },
    "e5": {
      "from": "appp",
      "to": "dbp",
      "fromSide": "bottom",
      "toSide": "top",
      "style": "dashed"
    },
    "e6": {
      "from": "appw",
      "to": "dbw",
      "fromSide": "bottom",
      "toSide": "top"
    },
    "e7": {
      "from": "apph",
      "to": "dbh",
      "fromSide": "bottom",
      "toSide": "top"
    }
  },
  "boxes": {
    "b0": {
      "x": 10,
      "y": 30,
      "w": 220,
      "h": 430,
      "label": "primary",
      "color": "green",
      "opacity": 0.04
    },
    "b1": {
      "x": 330,
      "y": 30,
      "w": 220,
      "h": 430,
      "label": "pilot light · RTO hours · RPO minutes",
      "color": "amber",
      "opacity": 0.04
    },
    "b2": {
      "x": 650,
      "y": 30,
      "w": 220,
      "h": 430,
      "label": "warm standby · RTO minutes",
      "color": "blue",
      "opacity": 0.04
    },
    "b3": {
      "x": 970,
      "y": 30,
      "w": 220,
      "h": 430,
      "label": "hot standby · RTO seconds",
      "color": "purple",
      "opacity": 0.04
    }
  },
  "texts": {
    "t1": {
      "x": 40,
      "y": 520,
      "text": "cost grows left → right; downtime shrinks the same way.\nPick the cheapest tier whose RTO/RPO the business\ncan actually sign — then DRILL it. An unrehearsed\nfailover is a second outage.",
      "color": "amber",
      "size": 12
    }
  },
  "meta": {
    "createdAt": "2026-07-13T09:00:00.000Z",
    "modifiedAt": "2026-07-13T09:00:00.000Z"
  }
}