2

I have read that there is a memory leak occurring in both node.js websocket modules ws and socket.io. It has existed for years and am wondering how to fix it.

It is mentioned in the following, to name a few:

Given it is now 2021, is setting the perMessageDeflate key to false and perhaps preloading jemalloc still the best solution?

Normajean
  • 121
  • 1
  • 5
  • I too have observed this in ws/socketio clients, not w/ nodejs though. I have observed this with socketio in python, websockets in nim (to a limited extent till now), but interestingly, when I used rust socketio, I saw very very little (total usage increased from ~300 MB to ~350 MB in about 4 days of continuous run) increase in memory usage. I don't really know the cause, just adding this observation here, hoping to collectively reach to any solution for this, – 0xc0de Aug 16 '22 at 10:08

1 Answers1

0

My rudimentary understanding of this issue is as follows (don't quote me on it):

  • the ws node.js module (i.e. the websockets module) and the socket.io node.js module both use another module called zlib. This module is responsible for compressing any messages when they are sent via websocket.
  • the zlib module has had a problem in the past relating to memory fragmentation, which mimics a memory leak (i.e. it is not actually a memory leak but memory fragmentation).
  • the compression of messages is disabled by default on the server but enabled by default on the client (e.g. browser). If we disable it, the zlib module is not used, which will remove the memory fragmentation problem.
  • To disable the compression on the client (e.g. browser), we give the perMessageDeflate key in your server code the value false. That is:

const wss = new WebSocket.Server({ server:httpsServer, perMessageDeflate: false });

Obviously this isn't a solution for people wanting to compress their messages. But it is worth mentioning that:

  • the memory fragmentation issue with zlib has apparently been PARTIALLY fixed with https://github.com/websockets/ws/pull/1204 but it does seem to still be a problem; and
  • the benefit of compressing small messages, like small pieces of text, has been debated. Some even state that compressing small messages will make things slower. If you are working with larger data, like images or video, you may find success by compressing it yourself (i.e. without ws/socket.io/zlib) before sending it through a websocket.

Also, some have noted that setting perMessageDeflate: false only reduces the problem, but does not entirely solve the problem. I would direct your attention to this discussion, where it is said that SOME residual and constant (i.e. not increasing) memory use from opening and closing websockets is normal (I'm not necessarily saying this is correct by the way): https://github.com/websockets/ws/issues/804#issuecomment-302612661

As for preloading Jemalloc, it does not seem that this fixes the issue. Although if the above code doesn't work, it is certainly worth looking into (or trying).

So is preMessageDeflate: false the best solution right now? From my understanding, I would say yes.

If anyone has corrections or more information on this please add.

Normajean
  • 121
  • 1
  • 5