Runbook: Redis down / unreachable¶
Prerequisites¶
- Interim
maidCLI (MAID_SRC): there is no system-widemaidbinary until M1.4 (install.shleaves/opt/maid/venvempty), so the CLI runs from a source checkout.export MAID_SRC=/path/to/maid-checkoutand build its venv once:sudo -u maid-engine -H uv sync --frozen --project "${MAID_SRC}"(uv:/opt/maid/current/.uv/bin/uv). Commands below run"${MAID_SRC}/.venv/bin/maid"as themaid-engineuser; insidebash -cblocksMAID_SRCis forwarded via--preserve-env=MAID_SRC. - Tools:
maid-admin,redis-cli,systemctl,journalctl,df. - Access: root, or an equivalently broad
sudogrant — this runbook runssudo systemctl/sudo journalctlon the instance units, which the narrowmaid-adminpriv-helper allowlist (packaging/sudoers/maid-admin.template) does not grant (it only covers fixedmaid-admin <verb>calls). There is nomaid-opsgroup in the packaging — only themaid-admingroup plus themaid-engineservice user (the restore/cleanup units run asroot). - Env file:
/etc/maid/<inst>.env—MAID_REDIS_URL. - Paths to know:
/var/lib/redis/— RDB / AOF data/var/log/redis/orjournalctl -u redis/etc/redis/redis.conf(Debian) or/etc/redis.conf(RHEL)- Audit access:
tail -f /var/log/maid/ops-audit.jsonl. - Escalation: see ./escalation-contacts.md.template.
Symptoms¶
Summary¶
- AI dialogue queue depth grows; NPC responses get slow or empty.
maid-admin status --instance <inst>showsredis: unreachable.- Engine journal:
redis.exceptions.ConnectionError: Error 111 connecting to 127.0.0.1:6379. Connection refused. /readyzis typically still green — Redis is cache-only in MAID v1 and is not on the critical path for core gameplay (login, movement, combat, persistence).
Detection¶
maid_redis_connection_errors_totalrate > 0 for > 60 s.maid_ai_dialogue_queue_depthclimbing.- Doctor:
maid-admin doctor --phase runtime --instance <inst>reportsredis_reachable: warn(warn, not fail — see "Cache-only" note below).
Blast radius¶
- Players affected: anyone interacting with AI NPCs sees degraded dialogue (longer latency, no recall of recent in-conversation context).
- Core gameplay (look / move / get / drop / combat / chat between players) is unaffected.
- Data at risk: none persistent. Redis in MAID v1 is a cache. NPC episodic memory lives in Postgres via the consolidation pipeline; Redis only holds the working-set cache and dialogue session state. When Redis returns, the cache repopulates from PG on demand.
- AI/external systems: prompt-build context that depends on cached memory / relationship lookups will refetch from PG; expect a brief latency spike during warm-up.
Cache-only invariant: if a future change makes Redis authoritative (e.g., moves the leader-lease store off Postgres into Redis), this runbook MUST be revised. As of M1.2 the lease store is Postgres (
leader_locktable); Redis is not the lease store. N/A: "Redis hosts the leader lease" — false for MAID v1.
Diagnostic Steps¶
First 5 minutes (LITERAL commands)¶
# 1. Confirm scope: gameplay should still work. Do NOT declare maintenance unless players report login failures.
maid-admin status --instance <inst> --json | jq '.redis, .ai_dialogue'
# 2. Capture state
sudo journalctl -u redis --since "-15 min" \
> ./incident-redis-$(date -u +%Y%m%dT%H%M%SZ).log
sudo systemctl status redis --no-pager
# 3. Is Redis even running?
redis-cli ping || echo "redis ping failed exit=$?"
# 4. Disk OK on /var/lib/redis ? (Redis refuses writes when AOF/RDB cannot persist)
df -h /var/lib/redis
Investigation¶
Decision tree:
systemctl status redis
├── active (running)?
│ └── yes → connectivity / auth issue
│ - check bind address vs MAID_REDIS_URL
│ - check `requirepass` vs the URL's password
│ - `redis-cli config get maxmemory` — full?
└── not running?
└── journalctl -u redis --since "-30 min"
- "Can't save in background: fork: Cannot allocate memory" → host OOM, see ./oom_loop.md
- "Write error saving DB on disk: No space left" → see ./disk_full.md
- "MISCONF Redis is configured to save RDB snapshots, but it's currently unable to persist on disk" → check disk
- clean exit / `systemctl stop` → someone stopped it; check audit and `last`
Useful queries once Redis is back:
redis-cli info memory | grep -E 'used_memory_human|maxmemory_human|maxmemory_policy'
redis-cli info persistence | grep -E 'loading|rdb_last_save_time|aof_enabled'
redis-cli info clients
redis-cli --bigkeys # find any pathological keys causing memory bloat
Resolution Steps¶
Mitigation¶
-
Redis crashed cleanly:
Engine reconnects automatically. Warn AI users: dialogue context for in-flight conversations is lost (working set was in Redis). NPC long-term memory is intact (lives in Postgres). -
Redis disk-full / persistence failures:
- See ./disk_full.md. Free space on
/var/lib/redis. -
As an emergency, disable AOF and switch to RDB-only:
File a follow-up ticket to re-enable AOF once disk is healthy. -
Redis evicting hot keys (
maxmemory_policy=allkeys-lruwith high eviction rate): -
Cache is undersized for current player population. Either bump
maxmemoryin/etc/redis/redis.confand restart, or shed AI load:See ./ai_provider_outage.md for the AI-disable / player-comms recipe.# `maid ops ai disable` is an M9 stub; use the functional kill-switch. sudo -u maid-engine "${MAID_SRC}/.venv/bin/maid" ops kill-switch trip "redis cache saturated" --confirm --instance <inst> -
Redis corruption (rare; AOF/RDB load fails):
This discards the cache. Acceptable because Redis is cache-only. Engine repopulates from PG on next access.
Recovery¶
redis-cli pingreturnsPONG.maid-admin doctor --phase runtime --instance <inst>redis_reachable: pass.maid_ai_dialogue_queue_depthreturns to baseline within ~5 min.
- If AI was disabled:
maid ops kill-switch reset --instance <inst>. - No player comms required if
/readyzstayed green throughout.
Post-incident¶
- File ticket with: Redis version, crash class, time to detect, time to recover.
- Consider raising
maxmemoryif eviction was the trigger. - If Redis went down for > 1 h during peak, evaluate whether NPC dialogue UX needs a graceful "NPC seems distracted..." fallback message instead of the current empty-response timeout.
Escalation¶
- Solo path: restart Redis; engine auto-reconnects.
- Hosting console URL: see ./escalation-contacts.md.template.
- DNS registrar URL: see ./escalation-contacts.md.template.
- Comms channel URL: see ./escalation-contacts.md.template.
- Peer operator: see ./escalation-contacts.md.template.
- If you cannot recover within 30 minutes AND AI dialogue is critical for your community: disable AI cleanly, post to comms channel, then defer the Redis fix. Core gameplay is unaffected.