Appearance
Ops Runbook — Gateway Redis & Memory Stores
Shared gateway state (JTI replay, rate limits, SSE tickets, Streams, SSE pub/sub) must not silently become per-replica memory in multi-instance deploys.
Boot policy (fail-closed)
| Topology | Required env | On Redis connect failure |
|---|---|---|
| Production / hardened multi-replica | REDIS_URL set; prefer REQUIRE_REDIS=true | Boot refuses — process exits |
| Single-replica pilot (memory) | ALLOW_MEMORY_STORE=true, REDIS_URL unset | N/A (memory by design) |
| Local / test | unset Redis | Soft-falls to memory with stderr warning |
REQUIRE_REDIS=true | REDIS_URL required | Boot refuses; ALLOW_MEMORY_STORE cannot override |
Do not set both REDIS_URL and ALLOW_MEMORY_STORE expecting soft failover. If REDIS_URL is set and Redis is down, boot refuses (no silent demotion).
Health checks
bash
curl -sS "$GATEWAY_URL/health"
curl -sS "$GATEWAY_URL/healthz" # aliasPayload fields:
| Field | Meaning |
|---|---|
status | ok or degraded (postgres down or store down) |
postgres | up | down | skipped |
store_backend | redis | memory |
store | Redis PING → up/down; memory → skipped |
Load balancers should treat status=degraded or HTTP ≠ 200 as unhealthy when Redis is mandatory.
Incident: replay possible across replicas
Symptom: Same JWT/jti accepted on more than one gateway instance; rate limits appear ineffective.
Likely cause: Instances booted with memory stores (ALLOW_MEMORY_STORE or Redis never connected).
Actions:
GET /health— confirmstore_backendisredisandstoreisupon every replica.- Ensure
REDIS_URLis identical and reachable from all replicas. - Set
REQUIRE_REDIS=trueand removeALLOW_MEMORY_STOREfor any multi-replica service. - Rolling restart after Redis is healthy; spent JTIs in memory are not recovered — treat as a short replay window and rotate partner keys if abuse is suspected.
Provisioning reminders
bash
pnpm --filter @waspada/gateway-api provisionSee also Phase B1–B4 runtime env table and RMIT mapping ops row.