What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more
To retry failed jobs in Node.js without repeating unintended side effects, combine a bounded retry policy with idempotent job handlers and a monitored path for jobs that exhaust their attempts. BullMQ, which stores jobs in Redis, and Amazon SQS offer different retry and operating models; neither makes external database writes, payments, or API calls safe to repeat automatically.
How to retry failed jobs in Node.js
A queue retry runs work again after a failure. That is useful when a problem may be temporary, but the first attempt may already have completed part of its work before failing—or the queue may deliver the job more than once. Treat retries as repeat executions, not proof that the earlier execution did nothing.
A reliable design has three parts: decide which failures merit another attempt, make repeated execution safe at the boundary where side effects occur, and route exhausted jobs to a place where they can be inspected and deliberately recovered.
Configure a bounded attempt count and delay
BullMQ marks a job failed when its processor throws an exception or when the job becomes stalled and exceeds the configured maximum stalled count. A processor should throw an Error object. To retry, configure attempts greater than one; without a backoff function, retries can happen immediately. See the BullMQ retry documentation.
#1 Best Overall
BullMQ supports fixed and exponential backoff, jitter, and custom strategies. In its example, an exponential backoff with a one-second seed and attempts: 3 yields retry delays of one, two, and four seconds. Three is the total number of attempts, including the initial run—not three extra retries. Jitter randomizes the delay to spread simultaneous retries; it does not ensure the failing service will recover.
There is no universal retry count. Set the budget and delay according to the downstream service’s limits, the cost of running the job, and how long the result can wait. A retry policy should stop within an operationally useful window rather than retrying indefinitely.
Retry transient failures, not permanent ones
Classify errors in application code. A temporary network failure or service limit may be worth retrying after a delay. Invalid input or a permanent business-rule rejection usually will not improve with another attempt. BullMQ supports custom backoff strategies; its UnrecoverableError lets a processor mark a job failed without using its configured retries. See BullMQ’s guidance on stopping retries.
Do these 3 things before closing this tab:
1Fix the driver behind crashes, sound loss and screen glitches2Clear out junk files and repair common Windows errors3Scan for outdated or missing drivers - takes under a minuteRank #2
How to make a job idempotent
Idempotence means that the final system state is the same whether a job succeeds on its first run or fails initially and succeeds after a retry. BullMQ recommends keeping jobs atomic and simple because a job that combines multiple writes and API calls is harder to reason about when it fails partway through. Its idempotent jobs guide describes this design goal.
For each job, identify the side effect that could happen twice, then give the logical operation a stable identity and persist completion or deduplication state where that side effect matters. If a task has several independent steps, consider splitting it into smaller steps with explicit state so a retry can determine what remains to be done. These are application design techniques, not guarantees supplied by every queue.
For example, before issuing a payment or sending a request to an external service, use an idempotency key or another deduplication mechanism supported by that service, when available. For a database change, a unique operation record or a transactionally recorded state transition may help prevent the same logical operation from being applied twice. The correct mechanism depends on the side effect and where its durable state lives.
Rank #3
Why queue job IDs are not end-to-end exactly-once protection
A queue-level identifier can help prevent duplicate enqueueing within the queue’s own state and retention rules, but it cannot by itself make an external payment, email, or API call idempotent. BullMQ documents custom jobId handling and places responsibility for uniqueness on the caller; see BullMQ job IDs. Do not infer end-to-end exactly-once side effects from a broker’s deduplication feature.
The Tool Desk
Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →What should happen after a job fails repeatedly?
When a job exhausts its retry budget, it needs a visible failure path rather than silent disappearance. A dead-letter queue (DLQ) isolates messages that could not be processed so operators can inspect the failure and decide whether a fix makes replay safe. A DLQ improves recovery and observability; it does not make the original handler idempotent.
Amazon SQS dead-letter queues and redrive
In Amazon SQS, configure a source queue’s redrive policy with a DLQ and a maxReceiveCount. Once a message reaches that receive threshold, SQS moves it to the DLQ. AWS recommends avoiding a threshold so low that messages are moved after too few processing opportunities. The DLQ must exist before configuration and must be in the same AWS account and Region as the source queue. See AWS dead-letter queue documentation.
Rank #4
Operators can inspect message contents and logs to diagnose failures, then use redrive to return messages for processing after deciding the underlying problem is fixed and replay is safe. Set up alarms and retain enough diagnostic context to establish what failed, which attempt failed, and whether the operation may already have partially completed. Redrive is a controlled recovery action, not a substitute for understanding the failure.
For standard queues, AWS says a message’s expiration after transfer to a DLQ is based on its original enqueue time. AWS recommends setting DLQ retention longer than source-queue retention. For FIFO queues, do not use a DLQ when moving a failed message aside would break the exact order of messages or operations that the application requires.
BullMQ and exhausted-job handling
The cited BullMQ retry documentation describes attempts, backoff, and unrecoverable failures, but does not establish a native DLQ feature. If choosing BullMQ, verify its current documentation for the exact exhausted-job monitoring, retention, and replay mechanism you plan to use; do not assume an SQS-style DLQ is built in.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Choosing between BullMQ and Amazon SQS
These are different operating models, not interchangeable products: BullMQ is a Node.js queue library whose jobs are held in Redis and processed by workers; SQS is a hosted queue service with source-queue and DLQ configuration. Choose according to how the application will run its queue, handle failures, and recover work—not on an assumption that either eliminates duplicate side effects.
| Decision | BullMQ over Redis | Amazon SQS |
|---|---|---|
| Queue model | Node.js queue library; jobs are held in Redis and processed by workers. BullMQ queue documentation | Hosted queue service with source-queue and DLQ configuration. AWS DLQ documentation |
| Retry and failure handling | Per-job attempts, fixed or exponential backoff, jitter, custom strategy, and an unrecoverable-error path. Retries; unrecoverable failures | Redrive policy moves messages after the configured receive count; AWS advises against setting the threshold too low. AWS DLQ documentation |
| Duplicate handling | Design jobs to be idempotent; this is a job-design pattern, not automatic protection for external side effects. BullMQ idempotent jobs | Standard queues provide at-least-once delivery, so consumers should tolerate duplicate processing. AWS delivery documentation |
| Dead-letter queue | A native DLQ is not established by the cited retry pages; verify current BullMQ documentation for your implementation. | AWS documents DLQ configuration and redrive. AWS DLQ documentation |
| Ordering concern | Confirm required ordering behavior against current BullMQ documentation for the exact configuration. | Avoid a DLQ for a FIFO queue if removing a failed message would violate required exact ordering. AWS DLQ documentation |
Implementation checklist
- Set a finite attempt count and a delay strategy suited to the downstream service.
- Classify errors so temporary failures can retry while permanent failures stop promptly.
- Make side effects safe to repeat with stable operation identity and durable deduplication or completion state where needed.
- Record enough context to diagnose partial work without exposing sensitive data in logs or messages.
- Monitor exhausted jobs or the DLQ, and define who can inspect and authorize replay.
- Before redrive, verify the cause is fixed and that replay will not duplicate a side effect or violate ordering requirements.
Start with the simplest queue whose operating model and failure semantics fit the workload. Whatever the queue, design consumers to tolerate repetition and make exhausted work observable and recoverable. The documentation cited here does not provide comparative performance or cost measurements, so those choices require workload-specific evaluation.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

