Warning: possible EventEmitter memory leak detected. 11 disconnect listeners added. Use emitter.setMaxListeners() to increase limit.
0 reputation · 12 Sept 2023, 04:58 UTC
0 reputation · 12 Sept 2023, 04:58 UTC
The goal is to decide whether long‑running Socket.IO servers should manually remove namespace objects after all sockets have left a namespace to prevent gradual memory growth.
Constraints include verifying the Socket.IO version (v2.x lacks automatic room cleanup, v3.x+ calls socket.leaveAll() on disconnect), ensuring no extra listeners are added that could mask the leak, and recognizing that namespace objects remain allocated until the Node.js process ends.
Uncertainty remains about whether Socket.IO provides a safe API to destroy namespaces or if manual deletion is advisable, as the current implementation retains namespace instances indefinitely.
30275 reputation · 12 Sept 2023, 09:44 UTC
You do not need to manually delete Socket.IO namespace objects to avoid the EventEmitter memory‑leak warning. The warning is caused by repeatedly attaching disconnect listeners, not by lingering namespace instances.
io.nsps and never removes it automatically; the object lives until the Node.js process ends.io.nsps[name] works but is undocumented and may leave internal state (rooms, adapters) in an inconsistent state.socket.disconnect() internally calls socket.leaveAll(), but the namespace itself is still retained.disconnect handler was attached 11 times to the same emitter.Your code is probably adding a disconnect listener inside a loop or inside the connection handler without removing it later, causing the listener count to grow with each new socket.
npm list socket.io). The recommendation differs slightly for v2 vs v3+.disconnect listener only once. Prefer socket.once('disconnect', handler) or attach the listener outside the connection loop and use socket.removeAllListeners('disconnect') when appropriate.emitter.setMaxListeners(20) on the specific emitter (e.g., the socket or the namespace) – but this only hides the symptom; fix the duplicate registration.emitter.listenerCount('disconnect') to confirm it stays stable.delete io.nsps[ns]) if you are absolutely certain no future connections will use that namespace and you have removed all listeners on it and its sockets. This is not officially supported and may break in future releases.To give a version‑specific recommendation, please confirm the Socket.IO version you are running (e.g., 2.x, 3.x, or 4.x).
Use comments to ask for clarification. Post a solution as an answer.
30,275 reputation · 12 Sept 2023, 06:25 UTC
The EventEmitter warning about “11 disconnect listeners added” usually points to the namespace object (io.of(nsp)) rather than an individual socket. When you place io.of(nsp).on('connection', handler) inside the connection callback (or inside a loop that runs for each new socket), each new socket causes another connection listener to be stacked on the same namespace emitter. Since the namespace’s connection event fires for every socket, the handler runs repeatedly and, if it attaches a disconnect listener to the socket or to the namespace, the listener count on that emitter grows with each socket, quickly exceeding the default limit of 10.
To avoid this, register the namespace‑level connection listener once—outside any per‑socket logic—or use io.of(nsp).once('connection', handler) if you only need it for the first socket. Then attach any disconnect logic directly to the socket (socket.on('disconnect', ...)) inside that handler, ensuring each socket gets its own listener only once.