Explorer pages 500'd in prod with max_statement_time exceeded. Two-part root cause: (1) probes hit the heavy / → restart cascade (fixed in gitops, probes → /healthz); (2) the dashboard's unstable_cache had no request-coalescing, so a cold pod under a burst ran the two ~890k-row 30-day ledger aggregations once per concurrent miss; /economy/health was force-dynamic and entirely uncached.
Shared-Redis cache replacing per-pod memoisation, so the heavy aggregates recompute at most once per window for the whole fleet:
lib/redis.ts — lazy ioredis singleton from REDIS_*, TENANT-prefixed keys (DC/SC share one prod Redis), graceful in-memory fallback when REDIS_HOST unset.lib/cache.ts memo(key, windowMs, producer) — epoch-aligned windows (bucket = floor(now/windowMs)), stale-while-revalidate (serve prior window instantly, never block a request), cross-pod single-flight via a Redis lock (one recompute per window for the fleet), L1 map to absorb the synchronized client burst.AutoRefresh aligned to wall-clock window boundaries (+lag) so the client refresh lands in lockstep with the cache reset and hits the warm cache.REDIS_* env wired (prod → redis.production + app-secrets/REDIS_PASSWORD; dev → redis.development).Follow-up to the probe fix. SQL unchanged — only how often / how concurrently the aggregates run, and where the result is cached.