Skip to content
Plurafy

Child Processes and Process Management

Spawning and managing child processes in Node.js

You need to run CPU-intensive operations without blocking the event loop. You also need to run external programs or scripts. How do you manage child processes effectively?

Node.js provides multiple ways to spawn child processes, each with different use cases. Understanding fork, spawn, and exec helps you offload work and run external commands.

const { spawn, exec, execFile, fork } = require('child_process');
// spawn: Stream large output
const ls = spawn('ls', ['-lh', './']);
ls.stdout.on('data', (data) => {
console.log(`stdout: ${data}`);
});
// exec: Run shell command (small output)
exec('ls -lh', (error, stdout, stderr) => {
if (error) console.error(error);
console.log(stdout);
});
// execFile: Run file directly
execFile('node', ['script.js'], (error, stdout) => {
console.log(stdout);
});
// fork: Node.js process with IPC
const child = fork('worker.js');
child.send({ message: 'Hello from parent' });
// worker.js - Child process
process.on('message', (data) => {
// Do CPU-intensive work
let result = 0;
for (let i = 0; i < data.iterations; i++) {
result += Math.sqrt(i);
}
// Send result back
process.send({ result });
});
// main.js - Parent process
const { fork } = require('child_process');
const worker = fork('worker.js');
// Send work to worker
worker.send({ iterations: 1000000000 });
// Receive result
worker.on('message', (msg) => {
console.log('Result from worker:', msg.result);
});
// Parent remains responsive
console.log('Doing other work...');
const { fork } = require('child_process');
// Parent process
const child = fork('child.js');
// Send multiple messages
child.send({ cmd: 'getQuote', id: 1 });
child.send({ cmd: 'getQuote', id: 2 });
// Handle messages from child
child.on('message', (msg) => {
console.log(`Child response: ${msg.quote}`);
});
// Detect child exit
child.on('exit', (code) => {
console.log(`Child exited with code ${code}`);
});
// --- child.js ---
process.on('message', (msg) => {
if (msg.cmd === 'getQuote') {
process.send({
id: msg.id,
quote: 'Life is short'
});
}
});
const cluster = require('cluster');
const http = require('http');
const os = require('os');
if (cluster.isMaster) {
const numWorkers = os.cpus().length;
console.log(`Master process ${process.pid} spawning workers...`);
// Spawn worker processes
for (let i = 0; i < numWorkers; i++) {
cluster.fork();
}
// Handle worker exit
cluster.on('exit', (worker, code) => {
console.log(`Worker ${worker.process.pid} died`);
cluster.fork(); // Respawn
});
} else {
// Worker process
const server = http.createServer((req, res) => {
res.writeHead(200);
res.end(`Handled by worker ${process.pid}`);
});
server.listen(3000);
console.log(`Worker ${process.pid} started`);
}
const { spawn } = require('child_process');
const fs = require('fs');
// Use gzip compression via spawned process
const gzip = spawn('gzip', ['-c']);
const source = fs.createReadStream('input.txt');
const destination = fs.createWriteStream('input.txt.gz');
source
.pipe(gzip)
.pipe(destination)
.on('finish', () => {
console.log('Compression complete');
});
// Monitor stderr for errors
gzip.stderr.on('data', (data) => {
console.error(`stderr: ${data}`);
});
const { spawn } = require('child_process');
const child = spawn('node', ['slow-script.js']);
const timeout = setTimeout(() => {
console.log('Process took too long, killing...');
child.kill('SIGTERM'); // Send termination signal
}, 5000);
child.on('exit', (code, signal) => {
clearTimeout(timeout);
if (signal === 'SIGTERM') {
console.log('Process was terminated');
} else {
console.log(`Process exited with code ${code}`);
}
});
child.on('error', (err) => {
console.error('Failed to start process:', err);
});