0
0
Node.jsframework~5 mins

Worker pool pattern in Node.js

Choose your learning style9 modes available
Introduction

The worker pool pattern helps run many tasks at the same time without slowing down your main program. It uses a group of workers to share the work.

When you have many small tasks to do and want to finish them faster.
When your program needs to stay responsive while doing heavy work.
When you want to limit how many tasks run at once to avoid overload.
When you want to reuse workers instead of creating new ones each time.
When you want to handle tasks in parallel but control resource use.
Syntax
Node.js
const { Worker } = require('worker_threads');

class WorkerPool {
  constructor(numWorkers) {
    this.workers = [];
    this.freeWorkers = [];
    for (let i = 0; i < numWorkers; i++) {
      const worker = new Worker('./worker.js');
      this.workers.push(worker);
      this.freeWorkers.push(worker);
    }
  }

  runTask(taskData) {
    return new Promise((resolve, reject) => {
      if (this.freeWorkers.length === 0) {
        reject(new Error('No free workers'));
        return;
      }
      const worker = this.freeWorkers.pop();
      worker.once('message', (result) => {
        this.freeWorkers.push(worker);
        resolve(result);
      });
      worker.once('error', reject);
      worker.postMessage(taskData);
    });
  }

  close() {
    for (const worker of this.workers) {
      worker.terminate();
    }
  }
}

The Worker class comes from the worker_threads module in Node.js.

You create a pool by making several workers and keep track of which are free.

Examples
This creates a pool with 3 workers and runs a task sending number 10.
Node.js
const pool = new WorkerPool(3);
pool.runTask({ number: 10 }).then(console.log);
Runs another task and prints the result when done.
Node.js
pool.runTask({ number: 20 }).then(result => {
  console.log('Result:', result);
});
Sample Program

This example shows a worker file that squares a number sent to it. The main file creates a pool of 2 workers and runs 3 tasks. It prints the array of squared results.

Node.js
// worker.js
const { parentPort } = require('worker_threads');

parentPort.on('message', (task) => {
  // Simple task: square the number
  const result = task.number * task.number;
  parentPort.postMessage(result);
});

// main.js
const { Worker } = require('worker_threads');

class WorkerPool {
  constructor(numWorkers) {
    this.workers = [];
    this.freeWorkers = [];
    for (let i = 0; i < numWorkers; i++) {
      const worker = new Worker('./worker.js');
      this.workers.push(worker);
      this.freeWorkers.push(worker);
    }
  }

  runTask(taskData) {
    return new Promise((resolve, reject) => {
      if (this.freeWorkers.length === 0) {
        reject(new Error('No free workers'));
        return;
      }
      const worker = this.freeWorkers.pop();
      worker.once('message', (result) => {
        this.freeWorkers.push(worker);
        resolve(result);
      });
      worker.once('error', reject);
      worker.postMessage(taskData);
    });
  }

  close() {
    for (const worker of this.workers) {
      worker.terminate();
    }
  }
}

(async () => {
  const pool = new WorkerPool(2);
  const results = await Promise.all([
    pool.runTask({ number: 5 }),
    pool.runTask({ number: 10 }),
    pool.runTask({ number: 3 })
  ]).catch(console.error);
  console.log(results);
  pool.close();
})();
OutputSuccess
Important Notes

Workers run in separate threads, so they do not block the main program.

Always close workers when done to free resources.

If no workers are free, tasks can be queued or rejected depending on your design.

Summary

The worker pool pattern helps run many tasks at the same time efficiently.

It uses a fixed number of workers to share the work and keep your program fast.

You create workers, send tasks, get results, and then reuse workers for new tasks.