Temporary failures do not block the rest of the queue
Why it matters
A queue worker configured with concurrency: 1 can process exactly one job at a time. When that job fails and BullMQ schedules a 32-second exponential backoff retry, the worker is blocked from pulling the next available job for 32 seconds. In a FIFO queue, every subsequent recipient in the batch waits behind the failing job. CWE-400 covers resource exhaustion via uncontrolled resource consumption — a single failing job consuming the entire worker thread is the mechanism. ISO-25010:2011 reliability.fault-tolerance requires that a fault in one component does not propagate to unrelated operations.
Severity rationale
Medium because single-worker FIFO blocking causes throughput stalls and delivery delays rather than data loss, but affects all recipients in a campaign when any single job fails.
Remediation
Set worker concurrency to at least 2 so delayed retry jobs do not block queue processing in workers/email.worker.ts:
const worker = new Worker('email', processEmailJob, {
connection,
concurrency: 5
})
// BullMQ moves failed-with-backoff jobs to the 'delayed' set automatically
// — they do not block other jobs while waiting
For marketing sends, add a rate limiter to prevent concurrency from overwhelming ESP rate limits:
const marketingWorker = new Worker('email:marketing', processEmailJob, {
connection,
concurrency: 10,
limiter: { max: 50, duration: 1000 }
})
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