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.