DeployU
Interviews / Backend Engineering / What is the difference between `child_process` and `worker_threads`?

What is the difference between `child_process` and `worker_threads`?

conceptual Concurrency Interactive Quiz Code Examples

The Scenario

You are a backend engineer at a data processing company. You are building a new service that needs to perform a CPU-intensive operation, such as image processing or video encoding.

You know that you should not perform this operation on the main thread, because it will block the event loop. You are considering using either the child_process module or the worker_threads module to offload the operation to a separate thread.

The Challenge

Explain the difference between the child_process module and the worker_threads module. What are the pros and cons of each approach, and which one would you choose for this use case?

Wrong Approach

A junior engineer might not be aware of the difference between these two modules. They might just choose one at random, without considering the trade-offs between them.

Right Approach

A senior engineer would be able to provide a detailed explanation of the differences between `child_process` and `worker_threads`. They would also be able to explain the trade-offs between each approach and would have a clear recommendation for which one to use in this use case.

Step 1: child_process vs. worker_threads

Featurechild_processworker_threads
Process ModelCreates a new process.Creates a new thread within the same process.
MemoryEach process has its own memory space.Threads share the same memory space.
CommunicationCommunication between processes is done using IPC (inter-process communication).Communication between threads is done using message passing or shared memory.
Use CasesRunning external commands, creating long-running background processes.Performing CPU-intensive operations without blocking the event loop.

Step 2: Choose the Right Tool for the Job

For our use case, worker_threads is the best choice. It is more lightweight than child_process, and it allows us to share memory between the main thread and the worker thread, which can be more efficient.

Step 3: Code Examples

Here are some code examples that show the difference between the two approaches:

child_process:

// main.js
const { fork } = require('child_process');

const child = fork('worker.js');

child.on('message', (message) => {
  console.log('Message from child:', message);
});

child.send({ hello: 'world' });

// worker.js
process.on('message', (message) => {
  console.log('Message from parent:', message);
});

process.send({ foo: 'bar' });

worker_threads:

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

if (isMainThread) {
  const worker = new Worker(__filename);
  worker.on('message', (message) => {
    console.log('Message from worker:', message);
  });
  worker.postMessage({ hello: 'world' });
} else {
  parentPort.on('message', (message) => {
    console.log('Message from parent:', message);
  });
  parentPort.postMessage({ foo: 'bar' });
}

Practice Question

You need to run an external command, such as `git`, from your Node.js application. Which of the following would you use?