Fork a long live child process without affected by main process
Published on: 31st Jul 2025
Overview
In Node.js, it makes programming easy to fork a child process. You just need to call child_process.fork('your-script.js')
and that's it.
Long live child process? What is the user requirement?
Your user has a niche requirement where the child process should continue to run when the main process has crashed, exited or restarted.
The solution
Using child_process.fork()
. This can be achieved easily by setting the detached=true
option when calling fork()
.
The sample program
Let's create a JS file with the name of rnd-fork-1103-child-long-live.js
and it has the following codes:
const { fork } = require('child_process');
const process = require('process');
const fs = require('fs');
const show_log = (msg) => {
console.log((new Date).toISOString(), msg);
}
if (process.argv[2] === 'child') {
let f2 = __filename + '.log';
// the child process is now running on an independent process.
// As a result, console.log() will not work in the debug mode and we will have to write the message to a log file
// to confirm that the main process exited and the child process is still running.
fs.writeFileSync(f2, `${(new Date).toISOString()}:child(pid=${process.pid}):running\n`);
let i = 0;
const do_work = () => {
setTimeout(() => {
i++;
fs.appendFileSync(f2, `${(new Date).toISOString()}:child(pid=${process.pid}):working on something,i=${i}\n`);
if (i < 5) {
do_work();
}
}, 1000);
};
do_work();
} else {
// the main process
process.on('exit', () => {
show_log(`main(pid=${process.pid}):exit`);
});
show_log(`main(pid=${process.pid}):start`);
const child = fork(__filename, ['child'],
{
detached: true,
stdio: 'ignore'
}
);
child.send('helo from main process');
setTimeout(() => {
// unref after the child process has become alive
child.unref();
}, 2000);
}
Here's the output of the main process which exited at '06:29:34':
Debugger attached.
2025-07-31T06:29:32.529Z main(pid=12832):start
2025-07-31T06:29:34.537Z main(pid=12832):exit
Waiting for the debugger to disconnect...
While the output in rnd-fork-1103-child-long-live.js.log
file, the child process continue to run and exit at '06:29:37':
2025-07-31T06:29:32.748Z:child(pid=5044):running
2025-07-31T06:29:33.763Z:child(pid=5044):working on something,i=1
2025-07-31T06:29:34.773Z:child(pid=5044):working on something,i=2
2025-07-31T06:29:35.781Z:child(pid=5044):working on something,i=3
2025-07-31T06:29:36.784Z:child(pid=5044):working on something,i=4
2025-07-31T06:29:37.786Z:child(pid=5044):working on something,i=5
Explanations
- We fork a child process for the same JS file with the option of
detached=true
. - Then, we remove the object reference in the event loop by calling
unref()
after two seconds. The reason that we are doing this because the child process will take some time to run. If you callunref()
without any delay, the main process will exit before the child process runs. - The same JS file is running in a child and it is running on an independent process. The
console.log()
will not work in the debug mode because we create the child process withstdio='ignore'
option. As a result, the child process will not be able to dump any message on the debug screen. To overcome this problem, we will have to write the message to a log file. - The main process is now calling the
unref()
after two seconds and then the main process exits. - The child process will continue to run (even after the main process has exited). This can be verified by reviewing the log file.
- The child process has completed its job and exit.
Use case
-
The main process is providing the front end service while the child process is cleaning up the temporary files that have been created. For example, there are lots of concurrent users who are accessing a web application and generating many PDF files. The child process must clean up the temporary PDF file periodically regardless if the main process is running or not.
-
The child process is monitoring the main process and ensuring that the main process is always alive. As a result, to shut down the main process required to shut down the child process first.
-
The child process is providing data caching service (i.e., a shared service) and the main process might have to be restarted due to upgrade. Since the child process (i.e., the data caching service) will not be upgraded frequently, we may restart the main process without affecting the child process. As a result, the data in the cache remain unchanged and we don't have to reload the cached data.
Conclusion
fork()
has a special setting that allows the child process to stay alive even after the main process has exited. If you compare the fork()
against the Worker
, the Worker
will die when the main thread dies. In fact, it is difficult to find a suitable use case for this behavior.
Related posts
Back to #NODEJS blog
Back to #blog listing
Author
Lau Hon Wan, software developer.