Usage with PM2
PM2 is a production process manager for Node.js applications with a built-in load balancer. It allows you to keep applications alive forever, to reload them without downtime and to facilitate common system admin tasks.
You can find its documentation here: https://pm2.keymetrics.io/docs/usage/pm2-doc-single-page/
To scale a Socket.IO server with PM2, there are three solutions:
- disable HTTP long-polling on the client-side
const socket = io({
transports: ["websocket"]
});
Though in that case, there will be no fallback to HTTP long-polling if the WebSocket connection cannot be established.
use a distinct port for each worker, and a load-balancer like nginx in front of them
use
@socket.io/pm2
Installation
npm install -g @socket.io/pm2
If pm2 is already installed, you will have to remove it first:
npm remove -g pm2
@socket.io/pm2 can be used as a drop-in replacement for pm2, and supports all the commands of the class pm2 utility.
The only difference comes from this commit.
Usage
import { createServer } from "node:http";
import { Server } from "socket.io";
import { createAdapter } from "@socket.io/cluster-adapter";
import { setupWorker } from "@socket.io/sticky";
const httpServer = createServer();
const io = new Server(httpServer);
io.adapter(createAdapter());
setupWorker(io);
io.on("connection", (socket) => {
console.log(`connect ${socket.id}`);
});
// graceful shutdown
process.on("SIGINT", () => {
io.close((err) => {
process.exit(err ? 1 : 0);
});
});
// important: no httpServer.listen() here
export const apps = [{
script : "worker.js",
instances : "max", // one process per core
exec_mode : "cluster"
}];
And then run pm2 start ecosystem.config.js (or pm2 start worker.js -i 0). That's it! You can now reach the Socket.IO cluster on port 8080.
How it works
When scaling to multiple nodes, there are two things to do:
- enable sticky sessions so that the HTTP requests of a Socket.IO session are routed to the same worker
- use a custom adapter so that the packets are broadcast to all clients, even if they are connected to another worker
To achieve this, @socket.io/pm2 includes two additional packages:
The only difference with pm2 comes from this commit:
- the God process now creates its own HTTP server and routes the HTTP requests to the right worker
- the God process also relays the packets between the workers, so that
io.emit()correctly reaches all clients
Please note that if you have several hosts each running a PM2 cluster, you will have to use another adapter, like the Redis adapter.
The source code of the fork can be found here: https://github.com/socketio/pm2
Latest releases
We try to closely follow the releases of the pm2 package, but if there is any missing release, please ping us.
| Version | Release date | Release notes |
|---|---|---|
6.0.14 | June 2026 | link |
6.0.8 | June 2025 | link |
5.3.0 | May 2023 | link |
5.2.2 | January 2022 | - |
5.2.1 | June 2021 | - |