Skip to main content
The app is a Next.js deployment on Vercel. MongoDB is the source of truth for users and plans. Redis (REDIS_URL, ioredis) coordinates state that cannot live in a single serverless isolate: step locks, editor presence, short-lived caches, rate limits, and logout token deny-list. Without Redis, those features fall back to an in-process Map. That is fine on one next dev process. On Vercel it is not: each function instance has its own memory, so two principals can edit the same step without seeing each other’s lock.

System health

Super Admin snapshot of Redis memory, key counts, and flush/retry actions.

Collaboration locks

How a step lock is acquired, refreshed, and released from the form workspace.

Keyspace

POST /api/admin/health { "action": "flush-cache" } deletes only qb:published:*, year:*, and public:overview:*. It never FLUSHALLs and never drops locks, presence, rate-limit, or deny-list keys.

Fail-open vs fail-closed

If Redis is unreachable, the client backs off for 60 seconds (retry-redis on System clears that timer). Behavior then depends on the caller: Production fail-closed is VERCEL_ENV === 'production' or NODE_ENV === 'production' (src/lib/userAccess.js).

Connection

src/lib/mongodb.js caches the Mongoose connection on global.mongoose and a MongoClient promise for NextAuth. Restart npm run dev after schema changes so the model is not stale in that cache. src/lib/redis.js keeps one ioredis client on global.__d79Redis (maxRetriesPerRequest: 1, lazy connect). ioredis is a Next.js serverExternalPackages entry so it is not bundled by webpack/Turbopack.
Set REDIS_URL in every Vercel environment that serves more than one instance. Super Admin System health shows whether Redis is configured, healthy, or backing off — never the password.