Production Cheatsheet
One-screen launch gate. Cite: Going to Production, Connections, Concurrency, Graceful Shutdown, Sandboxed.
Redis config (NOT in your code)
| Setting | Value | Why |
maxmemory-policy | noeviction | Eviction silently corrupts queues. Only safe value. |
| Persistence | AOF, ~1s fsync | Survives restarts without losing pending jobs. Often off by default. |
Managed Redis usually ships as a cache (LRU + no persistence). Flip both before launch.
Connection rule
const connection = new IORedis({ maxRetriesPerRequest: null }); // MANDATORY
| Class | Held |
Queue | 1 (sharable) |
Worker | 1 + internal duplicate (blocking) |
QueueEvents | 1 + internal duplicate (blocking) |
new Queue('email', { prefix: 'myapp-prod', connection }); // isolate envs
Graceful shutdown
let down = false;
async function shutdown() {
if (down) return; down = true;
await worker.close(); // no new jobs; waits for active (NO self-timeout!)
await queue.close();
await connection.quit();
process.exit(0);
}
process.on('SIGTERM', shutdown).on('SIGINT', shutdown);
worker.close() never self-times-out. Race it vs your grace period, or accept long jobs stall & get re-queued elsewhere.
Scaling model
| Work type | Knob | Note |
| I/O-bound | concurrency: N (high) | Exploits event-loop wait time. |
| CPU-bound | More worker processes | Scales ~linearly. High concurrency hurts. |
| Blocks event loop | Sandboxed processor | useWorkerThreads: true (v3.13+). |
Idempotency — required
Retries, stalls, rate-limit re-queues, flow resumes all re-run jobs. Guard side-effects (idempotency keys, dedup flags, upserts). Non-idempotent = double charges / double sends.
🚀 Launch checklist
- ☑ Redis:
maxmemory-policy noeviction + AOF.
- ☑ All ioredis:
maxRetriesPerRequest: null.
- ☑
removeOnComplete + removeOnFail on every queue.
- ☑ SIGTERM/SIGINT →
worker.close() + connection.quit().
- ☑ Idempotent processors.
- ☑
concurrency for I/O; worker processes for CPU; sandbox if blocking.
- ☑ Metrics on + stalled → alert.
- ☑
upsertJobScheduler at boot (idempotent).
- ☑ Dead-letter queue for terminal failures.
- ☑
uncaughtException/unhandledRejection handlers (log + exit).
- ☑ Fail fast if Redis unreachable at startup.