{
  "docVersion": 1,
  "id": "template-flash-sale-survival",
  "name": "Flash sale — survival kit",
  "purpose": "Edge cache + token buckets absorb the crowd, sharded counters absorb the hot stock key, and a leveling queue lets the database consume the sale at its own pace.",
  "nodes": {
    "crowd": {
      "type": "users",
      "label": "1M Shoppers",
      "x": 20,
      "y": 240,
      "runtime": "T-0: everyone at once"
    },
    "cdn": {
      "type": "cdn",
      "label": "Edge / CDN",
      "x": 280,
      "y": 240,
      "runtime": "product page cached",
      "notes": "The crowd's reads die here. Only intents to BUY go further."
    },
    "rl": {
      "type": "ratelimiter",
      "label": "Rate Limiter",
      "x": 540,
      "y": 240,
      "runtime": "token bucket per user",
      "color": "amber"
    },
    "api": {
      "type": "k8s",
      "label": "Sale API",
      "x": 800,
      "y": 240,
      "runtime": "fast paths only",
      "color": "blue",
      "patterns": [
        "stateless",
        "autoscale"
      ],
      "notes": "Reads stock from cache shards, enqueues buys, sheds honestly past capacity: 'sold out' in 20ms beats a hang."
    },
    "stockcache": {
      "type": "cache",
      "label": "Stock Cache",
      "x": 1060,
      "y": 40,
      "runtime": "pre-warmed · shard-keyed"
    },
    "warm": {
      "type": "cron",
      "label": "Cache Warmer",
      "x": 1340,
      "y": 40,
      "runtime": "T-30min: preload"
    },
    "queue": {
      "type": "queue",
      "label": "Buy Attempts",
      "x": 800,
      "y": 480,
      "runtime": "leveled · at-least-once"
    },
    "worker": {
      "type": "worker",
      "label": "Order Workers",
      "x": 1060,
      "y": 480,
      "runtime": "consume at DB pace",
      "patterns": [
        "autoscale"
      ]
    },
    "counters": {
      "type": "keyvalue",
      "label": "Stock Counters ×16",
      "x": 1320,
      "y": 480,
      "runtime": "sharded — no hot key",
      "notes": "hash(user) picks a shard; each holds 1/16 of stock. Contention divides by 16, correctness sums back to exact."
    },
    "db": {
      "type": "database",
      "label": "Orders DB",
      "x": 1320,
      "y": 240,
      "runtime": "never meets the crowd",
      "patterns": [
        "replicated",
        "backup"
      ]
    }
  },
  "edges": {
    "e1": {
      "from": "crowd",
      "to": "cdn",
      "fromSide": "right",
      "toSide": "left",
      "label": "page loads",
      "animated": true
    },
    "e2": {
      "from": "cdn",
      "to": "rl",
      "fromSide": "right",
      "toSide": "left",
      "label": "buy clicks only"
    },
    "e3": {
      "from": "rl",
      "to": "api",
      "fromSide": "right",
      "toSide": "left",
      "label": "admitted · 429 + retry-after past budget",
      "patterns": [
        "rate-limit"
      ]
    },
    "e4": {
      "from": "api",
      "to": "stockcache",
      "fromSide": "right",
      "toSide": "left",
      "label": "stock reads",
      "patterns": [
        "cache-aside"
      ]
    },
    "e5": {
      "from": "api",
      "to": "queue",
      "fromSide": "bottom",
      "toSide": "top",
      "label": "buy → queued",
      "animated": true
    },
    "e6": {
      "from": "queue",
      "to": "worker",
      "fromSide": "right",
      "toSide": "left",
      "style": "dashed",
      "patterns": [
        "backpressure"
      ]
    },
    "e7": {
      "from": "worker",
      "to": "counters",
      "fromSide": "right",
      "toSide": "left",
      "label": "decrement shard hash(user)%16",
      "animated": true
    },
    "e8": {
      "from": "worker",
      "to": "db",
      "fromSide": "top",
      "toSide": "bottom",
      "label": "write order",
      "patterns": [
        "timeout",
        "bulkhead"
      ]
    },
    "e9": {
      "from": "warm",
      "to": "stockcache",
      "fromSide": "left",
      "toSide": "right",
      "label": "pre-warm T-30",
      "style": "dashed"
    }
  },
  "boxes": {
    "b1": {
      "x": 760,
      "y": 400,
      "w": 820,
      "h": 260,
      "label": "the only writers — sized for the DB, not the crowd",
      "color": "blue",
      "opacity": 0.04
    }
  },
  "texts": {
    "t1": {
      "x": 20,
      "y": 430,
      "text": "the survival ordering:\ncache absorbs reads → buckets meter intents →\nqueue absorbs writes → shards absorb contention.\nthe database never notices the sale",
      "color": "amber",
      "size": 12
    }
  },
  "meta": {
    "createdAt": "2026-07-13T09:00:00.000Z",
    "modifiedAt": "2026-07-13T09:00:00.000Z"
  }
}