Honestly, I feel like an idiot - I've been maintaining Next.js apps last few years, and thought Next.js is automatically running clustered in production.
Moreover, I did not find any nice solutions for running Next.js clusterized - everything is over-complicated with ton of code.
Well, turned out (at least for Next 12) it is really simple - and Google did not give me any nice answer, so I had to research on it by myself today.
So, here's the solution - mostly simply based on node cluster
docs:
const cluster = require('node:cluster');
const process = require('node:process');
const { cpus } = require('node:os');
const numCPUs = cpus().length;
if (cluster.isPrimary) {
console.log(`Primary ${process.pid} is running`);
// all the magic goes here.
// `setupPrimary` is altering cluster behaviour
// see docs: https://nodejs.org/api/cluster.html#clustersetupprimarysettings
cluster.setupPrimary({
// node_modules/.bin is directory for all runtime scripts,
// including `next`.
// we can work with it like with a common node package,
// so require.resolve simply gives us path for `next` CLI
exec: require.resolve('.bin/next'),
// args should skip first 2 arguments,
// "node" path and file to execute path
args: ['start', ...process.argv.slice(2)],
// just directly passing all the IO to not handle pipes
stdio: 'inherit',
// making stdout and stderr colored
shell: true,
});
for (let i = 0; i < numCPUs; i++) {
cluster.fork();
}
cluster.on('exit', (worker, code, signal) => {
console.log(`worker ${worker.process.pid} died`, { code, signal });
});
}
// we do not need to do "else" here as cluster will run different file
Top comments (2)
Good post!
How about
output: standalone
mode? How to clusterized the generatedserver.js
?Thanks. Iām going to try this. Anything else you can share about performance gains after this change?