{
  "id": 18262915,
  "title": "BullMQ in NestJS: Retries, Idempotency and Dead-Letter Queues",
  "url": "https://urgent.news/2026/11/05/bullmq-in-nestjs-retries-idempotency-and-dead-letter-queues",
  "topic": "tech",
  "section": "Tech",
  "published": "2026-11-05T06:33:53.000Z",
  "source": {
    "name": "Dev.to",
    "slug": "dev-to",
    "url": "https://dev.to/zforzain2000/bullmq-in-nestjs-retries-idempotency-and-dead-letter-queues-1h4p"
  },
  "original_language": "en",
  "account": "In the world of backend development, a queue that relies solely on blindly retrying failed jobs is often worse than having no queue at all. Such a queue can lead to double sending emails, double charging customers, and subsequently deleting evidence of the failed job. The article outlines a setup in NestJS that addresses these issues by implementing retries with backoff and jitter, ensuring jobs cannot run twice, and utilizing a dead-letter queue to keep terminal failures inspectable and replayable. The incident that prompted this setup involved a welcome email being sent three times due to a faulty retry logic. The recipient received three identical emails, support raised a ticket, and the developer learned a valuable lesson: background jobs should only be retried if running them twice is harmless, and failed jobs must be stored somewhere a human can find them. The solution involves a single NestJS module built with BullMQ 6.7.0 and @nestjs/bullmq 12.0.0. The configuration includes BullMQ's connection settings with maxRetriesPerRequest set to null to prevent the workers from aborting blocked Redis commands during blips. The removeOnFail option is set to keep failed jobs for inspection purposes, with a retention period of 30 days and a cap of 5000 failed jobs. This setup ensures that each failure is cheap to prevent and expensive to debug after the fact, as the three failures that a naive queue hides are avoided.",
  "summary": "A queue that retries blindly is worse than no queue at all. It double-sends the welcome email, double-charges the customer, and then deletes the evidence by retrying the same broken job until the failure looks like noise. This post builds the setup I actually run in NestJS: retries that back off with jitter, jobs that cannot run twice, and a dead-letter queue that keeps every terminal failure…",
  "key_points": [
    "BullMQ with NestJS implemented retries, idempotency, and dead-letter queues",
    "MaxRetriesPerRequest set to null to avoid blocking Redis commands",
    "Failed jobs retained for 30 days, capped at 5000 for inspection and replay"
  ],
  "editors_take": "Implementing idempotency and dead-letter queues transforms background processing from a source of duplicate errors into a reliable system where failed tasks remain inspectable and safe to replay.",
  "illustration": null,
  "coverage": {
    "outlets": 1,
    "also_reported_by": []
  },
  "ai_generated": true,
  "disclaimer": "Summaries, key points and the editor’s take are written by software from other outlets’ reporting and may contain errors — always check the linked original."
}