Why Use Sandboxed Processors?
When processors perform CPU-intensive operations, they block Node.js’s event loop, preventing the worker from:- Renewing job locks
- Checking for stalled jobs
- Responding to shutdown signals
- Fetching new jobs
- Running processor code in a separate process/thread
- Keeping the main worker’s event loop free for bookkeeping
- Enabling true parallel processing on multi-core systems
- Preventing one job from blocking others
Creating a Sandboxed Processor
Define your processor in a separate file:The processor file must be a path to a compiled JavaScript file (
.js, .cjs, .mjs). If you’re using TypeScript, compile it first or use a file extension like .ts that your runtime supports.File Path Options
BullMQ accepts several file path formats:Standard String Path
URL Instance (Recommended for Windows)
Automatic Extension Resolution
BullMQ automatically tries these extensions if not specified:Worker Threads vs Child Processes
BullMQ supports two sandboxing mechanisms:Child Processes (Default)
Uses Node’schild_process.fork() to spawn separate processes:
- Isolation: Complete process isolation
- Memory: Separate memory space per process
- Overhead: Higher resource usage
- Stability: Process crash doesn’t affect main worker
Worker Threads (v3.13.0+)
Uses Node’sworker_threads module:
- Performance: Lower overhead than child processes
- Memory: Shared memory possible (with SharedArrayBuffer)
- Startup: Faster thread creation
- Resource usage: Less demanding than processes
Worker threads are lighter than child processes but still require duplicating the Node.js runtime. They’re not as lightweight as threads in other languages.
Sandboxed Job API
TheSandboxedJob interface provides a subset of the full Job API:
Handling Cancellation in Sandboxed Processors
Sandboxed processors automatically support cancellation through theAbortSignal:
TypeScript with Sandboxed Processors
For TypeScript projects, compile your processor files:1
Write processor in TypeScript
2
Configure TypeScript compilation
3
Compile TypeScript
4
Reference compiled file in worker
Concurrency with Sandboxed Processors
Set concurrency to match your CPU cores:Error Handling
Errors in sandboxed processors are caught and mark the job as failed:Performance Considerations
Process/Thread Overhead
Each sandboxed job requires spawning or reusing a process/thread:When NOT to Use Sandboxing
Sandboxing adds overhead. Don’t use it for:- I/O-bound operations: Database queries, HTTP requests, file I/O
- Fast computations: Operations that complete in milliseconds
- Low CPU usage: Tasks that don’t block the event loop
Monitoring Sandboxed Workers
Best Practices
1
Use sandboxing for CPU-intensive work only
Reserve sandboxing for computations, image processing, video encoding, etc.
2
Match concurrency to CPU cores
3
Prefer worker threads for most use cases
Worker threads have lower overhead than child processes.
4
Keep processor files self-contained
Minimize dependencies in processor files to reduce memory usage.
5
Handle errors gracefully
Catch and log errors in processors to aid debugging.
6
Monitor resource usage
Watch memory and CPU usage to tune concurrency.
Related Topics
Concurrency
Configure parallel processing
Stalled Jobs
Understand stalled job recovery
Cancelling Jobs
Cancel sandboxed jobs
Worker Options
Configure worker behavior
