Skip to content

[Rust] Add tokio-ws - WebSocket#814

Merged
MDA2AV merged 2 commits into
mainfrom
add-tokio-ws
Jun 6, 2026
Merged

[Rust] Add tokio-ws - WebSocket#814
MDA2AV merged 2 commits into
mainfrom
add-tokio-ws

Conversation

@MDA2AV
Copy link
Copy Markdown
Owner

@MDA2AV MDA2AV commented Jun 6, 2026

Description

A WebSocket echo server written directly on raw tokio, with the WebSocket protocol hand-rolled — no tokio-tungstenite, no wtx, no WS library.

Added as an engine-tier entry: the lowest-level way to serve echo-ws on the tokio reactor, so the leaderboard shows what the runtime itself does once framing is reduced to the minimum.

Hand-rolled

  • RFC 6455 handshake — request parsing, Sec-WebSocket-Accept derivation, and the 101 reply, with from-scratch SHA-1 + base64. The only dependencies are tokio and socket2.
  • Frame codec — streaming parser for 7/16/64-bit lengths, client→server unmasking, and partial frames split across reads. Echoes are re-emitted as unmasked server frames preserving FIN + opcode (so fragmentation passes through transparently). PingPong, Close echoed.

Serving model

One current_thread runtime per core, each binding :8080 with SO_REUSEPORT (kernel-sharded accept, no cross-core work-stealing). TCP_NODELAY per connection; outgoing echoes are batched per read so a pipelined burst flushes in one write. Same shape as the other one-thread-per-core engine entries (e.g. rust-epoll).

Tests

Subscribes to echo-ws and echo-ws-pipeline. Passes validate-ws.py (7/7) locally and via the Docker build.

🤖 Generated with Claude Code

Hand-rolled WebSocket echo server on raw tokio, with no WebSocket
library. The RFC 6455 handshake (including from-scratch SHA-1 + base64),
frame parser/masking, and echo write path are implemented directly on a
tokio TcpStream. Serving model is one current_thread runtime per core
with SO_REUSEPORT sharding, matching the other engine-tier entries.

Subscribes to echo-ws and echo-ws-pipeline. Passes validate-ws.py (7/7)
locally and via the Docker build.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@MDA2AV
Copy link
Copy Markdown
Owner Author

MDA2AV commented Jun 6, 2026

/benchmark -f tokio-ws

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 6, 2026

👋 /benchmark request received. A collaborator will review and approve the run.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 6, 2026

Benchmark Results

Framework: tokio-ws | Test: all tests

Test Conn RPS CPU Mem Δ RPS Δ Mem
echo-ws 512 4,439,600 6178.4% 44MiB NEW NEW
echo-ws 4096 4,504,517 6413.0% 173MiB NEW NEW
echo-ws 16384 4,220,007 6404.0% 592MiB NEW NEW
echo-ws-pipeline 512 66,801,988 6204.4% 40MiB NEW NEW
echo-ws-pipeline 4096 67,381,971 6423.2% 168MiB NEW NEW
echo-ws-pipeline 16384 62,045,219 6382.1% 593MiB NEW NEW
Full log
  Thread Stats   Avg      p50      p90      p99    p99.9
    Latency    123us    116us    187us    264us    489us

  329150112 frames sent in 5.00s, 329150079 frames received
  Throughput: 65.81M req/s
  Bandwidth:  439.33MB/s
  WS upgrades: 512
  WS frames:   329150079
  Latency samples: 329149040 / 329150079 responses (100.0%)
[info] CPU 6322.9% | Mem 43MiB

[run 3/3]
gcannon v0.5.3 [WS]
  Target:    localhost:8080/ws
  Threads:   64
  Conns:     512 (8/thread)
  Pipeline:  16
  Req/conn:  unlimited (keep-alive)
  Expected:  200
  Duration:  5s


  Thread Stats   Avg      p50      p90      p99    p99.9
    Latency    121us    117us    173us    227us    541us

  334009968 frames sent in 5.00s, 334009942 frames received
  Throughput: 66.78M req/s
  Bandwidth:  445.82MB/s
  WS upgrades: 512
  WS frames:   334009942
  Latency samples: 334008672 / 334009942 responses (100.0%)
[info] CPU 6204.4% | Mem 40MiB

=== Best: 66801988 req/s (CPU: 6204.4%, Mem: 40MiB) ===
[info] saved results/echo-ws-pipeline/512/tokio-ws.json
httparena-bench-tokio-ws
httparena-bench-tokio-ws

==============================================
=== tokio-ws / echo-ws-pipeline / 4096c (tool=gcannon) ===
==============================================
[info] ws-only framework — skipping HTTP probe (sleep 2s for startup)

[run 1/3]
gcannon v0.5.3 [WS]
  Target:    localhost:8080/ws
  Threads:   64
  Conns:     4096 (64/thread)
  Pipeline:  16
  Req/conn:  unlimited (keep-alive)
  Expected:  200
  Duration:  5s


  Thread Stats   Avg      p50      p90      p99    p99.9
    Latency    961us    950us   1.16ms   1.35ms   1.49ms

  336851312 frames sent in 5.00s, 336789136 frames received
  Throughput: 67.33M req/s
  Bandwidth:  449.57MB/s
  WS upgrades: 4096
  WS frames:   336789136
  Latency samples: 336789136 / 336789136 responses (100.0%)
[info] CPU 6123.6% | Mem 151MiB

[run 2/3]
gcannon v0.5.3 [WS]
  Target:    localhost:8080/ws
  Threads:   64
  Conns:     4096 (64/thread)
  Pipeline:  16
  Req/conn:  unlimited (keep-alive)
  Expected:  200
  Duration:  5s


  Thread Stats   Avg      p50      p90      p99    p99.9
    Latency    972us    963us   1.11ms   1.32ms   4.00ms

  336909856 frames sent in 5.00s, 336909856 frames received
  Throughput: 67.34M req/s
  Bandwidth:  449.65MB/s
  WS upgrades: 4096
  WS frames:   336909856
  Latency samples: 336908288 / 336909856 responses (100.0%)
[info] CPU 6423.2% | Mem 168MiB

[run 3/3]
gcannon v0.5.3 [WS]
  Target:    localhost:8080/ws
  Threads:   64
  Conns:     4096 (64/thread)
  Pipeline:  16
  Req/conn:  unlimited (keep-alive)
  Expected:  200
  Duration:  5s


  Thread Stats   Avg      p50      p90      p99    p99.9
    Latency    975us    957us   1.15ms   1.36ms   4.10ms

  335876320 frames sent in 5.00s, 335876013 frames received
  Throughput: 67.15M req/s
  Bandwidth:  448.25MB/s
  WS upgrades: 4096
  WS frames:   335876013
  Latency samples: 335874528 / 335876013 responses (100.0%)
[info] CPU 6139.4% | Mem 173MiB

=== Best: 67381971 req/s (CPU: 6423.2%, Mem: 168MiB) ===
[info] saved results/echo-ws-pipeline/4096/tokio-ws.json
httparena-bench-tokio-ws
httparena-bench-tokio-ws

==============================================
=== tokio-ws / echo-ws-pipeline / 16384c (tool=gcannon) ===
==============================================
[info] ws-only framework — skipping HTTP probe (sleep 2s for startup)

[run 1/3]
gcannon v0.5.3 [WS]
  Target:    localhost:8080/ws
  Threads:   64
  Conns:     16384 (256/thread)
  Pipeline:  16
  Req/conn:  unlimited (keep-alive)
  Expected:  200
  Duration:  5s


  Thread Stats   Avg      p50      p90      p99    p99.9
    Latency   4.24ms   4.21ms   4.63ms   5.43ms   13.60ms

  294874976 frames sent in 5.00s, 294612832 frames received
  Throughput: 58.90M req/s
  Bandwidth:  393.57MB/s
  WS upgrades: 16384
  WS frames:   294612832
  Latency samples: 294612832 / 294612832 responses (100.0%)
[info] CPU 5880.8% | Mem 553MiB

[run 2/3]
gcannon v0.5.3 [WS]
  Target:    localhost:8080/ws
  Threads:   64
  Conns:     16384 (256/thread)
  Pipeline:  16
  Req/conn:  unlimited (keep-alive)
  Expected:  200
  Duration:  5s


  Thread Stats   Avg      p50      p90      p99    p99.9
    Latency   4.19ms   4.20ms   4.61ms   5.32ms   10.60ms

  310488240 frames sent in 5.00s, 310226096 frames received
  Throughput: 62.02M req/s
  Bandwidth:  414.41MB/s
  WS upgrades: 16384
  WS frames:   310226096
  Latency samples: 310226096 / 310226096 responses (100.0%)
[info] CPU 6382.1% | Mem 593MiB

[run 3/3]
gcannon v0.5.3 [WS]
  Target:    localhost:8080/ws
  Threads:   64
  Conns:     16384 (256/thread)
  Pipeline:  16
  Req/conn:  unlimited (keep-alive)
  Expected:  200
  Duration:  5s


  Thread Stats   Avg      p50      p90      p99    p99.9
    Latency   4.22ms   4.19ms   4.58ms   7.42ms   10.70ms

  308432640 frames sent in 5.00s, 308170496 frames received
  Throughput: 61.61M req/s
  Bandwidth:  411.72MB/s
  WS upgrades: 16384
  WS frames:   308170496
  Latency samples: 308170496 / 308170496 responses (100.0%)
[info] CPU 5961.9% | Mem 615MiB

=== Best: 62045219 req/s (CPU: 6382.1%, Mem: 593MiB) ===
[info] saved results/echo-ws-pipeline/16384/tokio-ws.json
httparena-bench-tokio-ws
httparena-bench-tokio-ws
[info] rebuilding site/data/*.json
[updated] /home/diogo/actions-runner/_work/HttpArena/HttpArena/site/data/frameworks.json
[updated] /home/diogo/actions-runner/_work/HttpArena/HttpArena/site/data/echo-ws-16384.json
[updated] /home/diogo/actions-runner/_work/HttpArena/HttpArena/site/data/echo-ws-4096.json
[updated] /home/diogo/actions-runner/_work/HttpArena/HttpArena/site/data/echo-ws-512.json
[updated] /home/diogo/actions-runner/_work/HttpArena/HttpArena/site/data/echo-ws-pipeline-16384.json
[updated] /home/diogo/actions-runner/_work/HttpArena/HttpArena/site/data/echo-ws-pipeline-4096.json
[updated] /home/diogo/actions-runner/_work/HttpArena/HttpArena/site/data/echo-ws-pipeline-512.json
[updated] /home/diogo/actions-runner/_work/HttpArena/HttpArena/site/data/current.json
[info] done
[info] restoring loopback MTU to 65536

@MDA2AV
Copy link
Copy Markdown
Owner Author

MDA2AV commented Jun 6, 2026

/benchmark -f tokio-ws --save

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 6, 2026

👋 /benchmark request received. A collaborator will review and approve the run.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 6, 2026

Benchmark Results

Framework: tokio-ws | Test: all tests

Test Conn RPS CPU Mem Δ RPS Δ Mem
echo-ws 512 4,352,944 6332.2% 43MiB NEW NEW
echo-ws 4096 4,433,246 6228.7% 176MiB NEW NEW
echo-ws 16384 4,143,535 6399.5% 590MiB NEW NEW
echo-ws-pipeline 512 65,856,262 6216.1% 42MiB NEW NEW
echo-ws-pipeline 4096 66,930,970 6240.6% 173MiB NEW NEW
echo-ws-pipeline 16384 61,865,334 6397.0% 592MiB NEW NEW
Full log

  328492192 frames sent in 5.00s, 328529408 frames received
  Throughput: 65.67M req/s
  Bandwidth:  438.33MB/s
  WS upgrades: 512
  WS frames:   328529408
  Latency samples: 328490624 / 328529408 responses (100.0%)
[info] CPU 6359.4% | Mem 42MiB

[run 3/3]
gcannon v0.5.3 [WS]
  Target:    localhost:8080/ws
  Threads:   64
  Conns:     512 (8/thread)
  Pipeline:  16
  Req/conn:  unlimited (keep-alive)
  Expected:  200
  Duration:  5s


  Thread Stats   Avg      p50      p90      p99    p99.9
    Latency    123us    115us    184us    238us    630us

  329281312 frames sent in 5.00s, 329281312 frames received
  Throughput: 65.84M req/s
  Bandwidth:  439.66MB/s
  WS upgrades: 512
  WS frames:   329281312
  Latency samples: 329403056 / 329281312 responses (100.0%)
[info] CPU 6216.1% | Mem 42MiB

=== Best: 65856262 req/s (CPU: 6216.1%, Mem: 42MiB) ===
[info] saved results/echo-ws-pipeline/512/tokio-ws.json
httparena-bench-tokio-ws
httparena-bench-tokio-ws

==============================================
=== tokio-ws / echo-ws-pipeline / 4096c (tool=gcannon) ===
==============================================
[info] ws-only framework — skipping HTTP probe (sleep 2s for startup)

[run 1/3]
gcannon v0.5.3 [WS]
  Target:    localhost:8080/ws
  Threads:   64
  Conns:     4096 (64/thread)
  Pipeline:  16
  Req/conn:  unlimited (keep-alive)
  Expected:  200
  Duration:  5s


  Thread Stats   Avg      p50      p90      p99    p99.9
    Latency    969us    972us   1.14ms   1.28ms   1.63ms

  334087376 frames sent in 5.00s, 334024912 frames received
  Throughput: 66.77M req/s
  Bandwidth:  445.85MB/s
  WS upgrades: 4096
  WS frames:   334024912
  Latency samples: 334024912 / 334024912 responses (100.0%)
[info] CPU 6097.9% | Mem 153MiB

[run 2/3]
gcannon v0.5.3 [WS]
  Target:    localhost:8080/ws
  Threads:   64
  Conns:     4096 (64/thread)
  Pipeline:  16
  Req/conn:  unlimited (keep-alive)
  Expected:  200
  Duration:  5s


  Thread Stats   Avg      p50      p90      p99    p99.9
    Latency    986us    966us   1.16ms   1.32ms   4.10ms

  332086672 frames sent in 5.00s, 332085536 frames received
  Throughput: 66.40M req/s
  Bandwidth:  443.28MB/s
  WS upgrades: 4085
  WS frames:   332085536
  Latency samples: 332084336 / 332085536 responses (100.0%)
[info] CPU 6428.8% | Mem 167MiB

[run 3/3]
gcannon v0.5.3 [WS]
  Target:    localhost:8080/ws
  Threads:   64
  Conns:     4096 (64/thread)
  Pipeline:  16
  Req/conn:  unlimited (keep-alive)
  Expected:  200
  Duration:  5s


  Thread Stats   Avg      p50      p90      p99    p99.9
    Latency    978us    974us   1.17ms   1.32ms   1.49ms

  334648352 frames sent in 5.00s, 334654854 frames received
  Throughput: 66.90M req/s
  Bandwidth:  446.59MB/s
  WS upgrades: 4096
  WS frames:   334644246
  Latency samples: 334656608 / 334654854 responses (100.0%)

  WARNING: 10608/334654854 responses (0.0%) had unexpected status (expected 2xx)
[info] CPU 6240.6% | Mem 173MiB

=== Best: 66930970 req/s (CPU: 6240.6%, Mem: 173MiB) ===
[info] saved results/echo-ws-pipeline/4096/tokio-ws.json
httparena-bench-tokio-ws
httparena-bench-tokio-ws

==============================================
=== tokio-ws / echo-ws-pipeline / 16384c (tool=gcannon) ===
==============================================
[info] ws-only framework — skipping HTTP probe (sleep 2s for startup)

[run 1/3]
gcannon v0.5.3 [WS]
  Target:    localhost:8080/ws
  Threads:   64
  Conns:     16384 (256/thread)
  Pipeline:  16
  Req/conn:  unlimited (keep-alive)
  Expected:  200
  Duration:  5s


  Thread Stats   Avg      p50      p90      p99    p99.9
    Latency   4.24ms   4.25ms   4.64ms   5.01ms   7.31ms

  296918336 frames sent in 5.00s, 296660016 frames received
  Throughput: 59.30M req/s
  Bandwidth:  396.29MB/s
  WS upgrades: 16384
  WS frames:   296660016
  Latency samples: 296660016 / 296660016 responses (100.0%)
[info] CPU 5918.9% | Mem 552MiB

[run 2/3]
gcannon v0.5.3 [WS]
  Target:    localhost:8080/ws
  Threads:   64
  Conns:     16384 (256/thread)
  Pipeline:  16
  Req/conn:  unlimited (keep-alive)
  Expected:  200
  Duration:  5s


  Thread Stats   Avg      p50      p90      p99    p99.9
    Latency   4.22ms   4.26ms   4.64ms   5.03ms   7.79ms

  309588816 frames sent in 5.00s, 309326672 frames received
  Throughput: 61.85M req/s
  Bandwidth:  413.28MB/s
  WS upgrades: 16384
  WS frames:   309326672
  Latency samples: 309326672 / 309326672 responses (100.0%)
[info] CPU 6397.0% | Mem 592MiB

[run 3/3]
gcannon v0.5.3 [WS]
  Target:    localhost:8080/ws
  Threads:   64
  Conns:     16384 (256/thread)
  Pipeline:  16
  Req/conn:  unlimited (keep-alive)
  Expected:  200
  Duration:  5s


  Thread Stats   Avg      p50      p90      p99    p99.9
    Latency   4.25ms   4.28ms   4.66ms   5.10ms   10.20ms

  306241088 frames sent in 5.00s, 305978944 frames received
  Throughput: 61.16M req/s
  Bandwidth:  408.67MB/s
  WS upgrades: 16384
  WS frames:   305978944
  Latency samples: 305978944 / 305978944 responses (100.0%)
[info] CPU 6077.5% | Mem 618MiB

=== Best: 61865334 req/s (CPU: 6397.0%, Mem: 592MiB) ===
[info] saved results/echo-ws-pipeline/16384/tokio-ws.json
httparena-bench-tokio-ws
httparena-bench-tokio-ws
[info] rebuilding site/data/*.json
[updated] /home/diogo/actions-runner/_work/HttpArena/HttpArena/site/data/frameworks.json
[updated] /home/diogo/actions-runner/_work/HttpArena/HttpArena/site/data/echo-ws-16384.json
[updated] /home/diogo/actions-runner/_work/HttpArena/HttpArena/site/data/echo-ws-4096.json
[updated] /home/diogo/actions-runner/_work/HttpArena/HttpArena/site/data/echo-ws-512.json
[updated] /home/diogo/actions-runner/_work/HttpArena/HttpArena/site/data/echo-ws-pipeline-16384.json
[updated] /home/diogo/actions-runner/_work/HttpArena/HttpArena/site/data/echo-ws-pipeline-4096.json
[updated] /home/diogo/actions-runner/_work/HttpArena/HttpArena/site/data/echo-ws-pipeline-512.json
[updated] /home/diogo/actions-runner/_work/HttpArena/HttpArena/site/data/current.json
[info] done
[info] restoring loopback MTU to 65536

@MDA2AV MDA2AV merged commit c3ac1af into main Jun 6, 2026
@MDA2AV MDA2AV deleted the add-tokio-ws branch June 7, 2026 14:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant