Why Graceful Shutdown Matters
When a worker shuts down abruptly:- Jobs being processed are left in the
activestate - These jobs become “stalled” and must be recovered by the stalled job checker
- Incomplete work may need to be repeated
- Resources may not be cleaned up properly
- Current jobs complete normally (or fail gracefully)
- No new jobs are fetched
- Worker closes cleanly after all work is done
- Minimal job recovery needed
Basic Graceful Shutdown
Call theclose() method on your worker:
What Happens During close()
1
Worker marked as closing
The worker stops fetching new jobs from the queue.
2
Wait for active jobs
The
close() call waits for all currently processing jobs to complete or fail.3
Cleanup resources
The worker closes Redis connections and releases resources.
4
Close resolves
The
close() promise resolves once everything is cleaned up.Force Shutdown
If you need to close immediately without waiting for jobs:- Emergency situations requiring immediate termination
- Worker is stuck and not responding
- Maximum shutdown time exceeded
Handling Process Signals
Listen for termination signals to gracefully shut down:Shutdown with Timeout
The
close() method does not have a built-in timeout. You should implement your own timeout logic to prevent indefinite waiting.Worker Lifecycle Events
Monitor the shutdown process:Multiple Workers Shutdown
When running multiple workers, close them all:Kubernetes/Docker Deployment
For containerized environments, handle the SIGTERM signal that Kubernetes sends:Kubernetes Configuration
Stalled Job Recovery
In BullMQ v2.0+, the
QueueScheduler is no longer needed for stalled job recovery. Workers automatically handle stalled jobs.- Network failures
- Worker crashes before shutdown
- Force shutdown (close with
true)
Pausing Before Shutdown
Alternatively, pause the worker before closing:Best Practices
1
Always use graceful shutdown
Implement signal handlers for SIGTERM and SIGINT in production.
2
Set appropriate timeouts
Ensure shutdown timeout is longer than your longest job duration.
3
Implement force shutdown fallback
Use timeout-based force shutdown to prevent indefinite waiting.
4
Monitor shutdown time
Log and track how long shutdowns take to identify slow jobs.
5
Test shutdown behavior
Regularly test graceful shutdown in staging environments.
6
Configure container grace periods
In Kubernetes/Docker, set terminationGracePeriodSeconds appropriately.
Troubleshooting
Shutdown Hangs Indefinitely
Cause: Jobs are taking too long to complete. Solution: Implement a shutdown timeout and force close:Jobs Keep Stalling After Restart
Cause: Jobs take longer thanlockDuration.
Solution: Increase lock duration:
Worker Doesn’t Respond to SIGTERM
Cause: No signal handler attached. Solution: Add signal handlers as shown above.Related Topics
Pausing Queues
Pause workers without closing
Stalled Jobs
Understanding stalled job recovery
Cancelling Jobs
Cancel jobs during shutdown
Worker Options
Configure worker behavior
