CodePark/ questions / BullMQ & Node job queues
START PRACTICINGPRACTICE
Backend question · Message queues & streaming › BullMQ & Node job queues

What does the concurrency option of a BullMQ worker do, and when does raising it help or not help?

const worker = new Worker("emails", async (job) => {
  await sendEmail(job.data);
}, { connection, concurrency: 50 });

concurrency is the number of jobs one Worker instance processes at the same time. With concurrency: 50, the worker keeps up to 50 jobs active. All of them run inside the same Node process and the same event loop.

When it helps: jobs that are I/O bound. I/O bound means the job spends most of its time waiting on the network or disk. Examples:

  • sending emails
  • calling APIs
  • writing to a database

While one job waits on the network, the event loop runs another one, so many jobs make progress together.

Watch the limits of the systems you call. 50 jobs at once can mean 50 database connections. It can also go over a provider's rate limit. BullMQ's rate limiter can enforce that limit for you.

When it does not help: CPU-bound work, such as image resizing or PDF generation. One event loop still runs only one piece of JavaScript at a time. Heavy CPU work also blocks the worker from renewing its job locks, and this can cause stalled jobs. For CPU work, use one of these:

  • sandboxed processors, which run each job in a separate process
  • more worker processes, spread across CPU cores and machines
  • Concurrency is the number of jobs one worker processes at the same time.
  • All these jobs share one event loop in the same process.
  • It helps I/O-bound jobs, but watch database connection pools and rate limits.
  • It does not help CPU-bound jobs, so use sandboxed processors or more processes for them.