Skip to content

Heavy memory usage difference between 0.24 and 0.25 #480

@Totodore

Description

@Totodore

One of the user of socketioxide, a socket.io implementation made with tokio-tungstenite reported a really high memory usage (around 3GB for 50K sockets) when benchmarking a basic ping/pong socket.io server.

I checked a bit and it appears that there is a big difference between 0.24 and 0.25 versions of tungstenite/tokio-tungstenite. I took the official echo example to do this and benchmarked with 10K sockets echoing messages.

Here is the repository with all the details and results: https://github.com/Totodore/tokio-tungstenite-mem-usage

Recap :

tokio-tungstenite 0.24.0

  • Calls to allocation functions: 341,152 (3,694/s)
  • Temporary allocations: 60,021 (17.59%, 649/s)
  • Peak heap memory usage: 106.1MB
  • Peak RSS: 119.6MB
  • Total runtime: 1min32s

tokio-tungstenite 0.25.0

  • Calls to allocation functions: 324,172 (3,064/s)
  • Temporary allocations: 68,341 (21.08%, 646/s)
  • Peak heap memory usage: 908MB
  • Peak RSS: 936MB
  • Total runtime: 1min45s

Tokio-tungstenite 0.25 eats 908MB of RAM vs 106.1MB for 0.24!

Possible causes

0.25 introduces the Bytes struct in the Message API. As it shares data directly received from the internal socket, I suspect that the cause is around this feature. According to the heaptrack trace, it comes from the FrameCodec in_buffer which seems to grows if it doesn't have enough space. But no reference to the message content is kept so the FrameCodec should not grow that much.

I also tried without echoing anything and the results are the same:

    let (_write, mut read) = ws_stream.split();
    while let Some(_msg) = read.try_next().await.unwrap() {}

Image

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions