Queue backed by durable persistent storage
Why it matters
An in-memory queue — a plain array, a Map, or a setInterval drain loop — lives entirely in the Node.js process heap. When the process restarts after a deploy, a crash, or an OOM kill, every pending email in that queue vanishes. Recipients who triggered a password-reset or order-confirmation during that window never receive it. CWE-400 covers resource exhaustion from unbounded growth; here the risk is the inverse — the store has zero durability. ISO-25010:2011 reliability.fault-tolerance requires components to survive fault conditions; in-process storage is the antithesis of that property.
Severity rationale
Critical because a process restart silently drops all pending sends, and the application has no mechanism to detect or replay the lost jobs.
Remediation
Replace any in-process queue with BullMQ backed by Redis, or pg-boss backed by PostgreSQL in lib/queue.ts. Initialize the connection at startup with an explicit URL from environment variables:
// lib/queue.ts
import { Queue, Worker } from 'bullmq'
import IORedis from 'ioredis'
const connection = new IORedis(process.env.REDIS_URL, {
maxRetriesPerRequest: null
})
export const emailQueue = new Queue('email', { connection })
For serverless deployments where Redis cost is prohibitive, use pg-boss against your existing DATABASE_URL.
DetectionPro
The detection method for this pattern is part of AuditBuffet Pro.
The full method (what to look for, pass and fail conditions, and how results get reported) ships inside the Sending Pipeline & Infrastructure Audit. The pattern definition, severity rationale, and remediation remain openly licensed under CC-BY-4.0.
External references
- cwe · CWE-400 — Uncontrolled Resource Consumption
- iso-25010:2011 · reliability.fault-tolerance — Fault Tolerance
Taxons
History
- 2026-04-18·v1.0.0·Initial import from sending-pipeline-infrastructure·automated