I built sockudo-ws: A WebSocket library faster than uWebSockets (C++) with HTTP/2, HTTP/3, and io_uring support

58 points AcanthopterygiiKey62 35 comments

Hey r/rust! I'm excited to share sockudo-ws, an ultra-low latency WebSocket library I've been working on for high-frequency trading and real-time systems.

The Big Win

We're now ~17% faster than the next fastest Rust WebSocket library, and we actually match or beat uWebSockets (the C++ industry standard) in throughput benchmarks:

Library Total Time (100k msgs)
sockudo-ws 10.2ms
fastwebsockets 12.0ms
tokio-tungstenite 34.8ms

Against uWebSockets, we're achieving 1.02-1.03x their throughput across various workloads while providing a safe, ergonomic Rust API.

What Makes It Fast?

  • SIMD acceleration (AVX2/AVX-512/NEON) for frame masking and UTF-8 validation
  • Zero-copy parsing - direct buffer access without intermediate allocations
  • Write batching (corking) - minimizes syscalls via vectored I/O
  • Zero-copy API via RawMessage that avoids String allocation for text messages

Modern Protocol Support

This is where things get interesting. sockudo-ws supports not just HTTP/1.1, but:

  • HTTP/2 WebSocket (RFC 8441) - multiplexed streams over a single connection
  • HTTP/3 WebSocket (RFC 9220) - WebSocket over QUIC with 0-RTT and no head-of-line blocking
  • io_uring - Linux kernel-level async I/O that can be combined with any protocol

The best part? All transports use the same API. Your WebSocket handler code works identically whether you're using HTTP/1.1, HTTP/2, HTTP/3, or io_uring underneath.

Production Ready

  • ✅ Autobahn compliant - passes all 517 test suite cases
  • ✅ permessage-deflate compression
  • ✅ Split streams for concurrent read/write
  • ✅ Tokio & Axum integration

Quick Example

use sockudo_ws::{Config, Message, WebSocketStream};
use futures_util::{SinkExt, StreamExt};

async fn handle(stream: TcpStream) {
    let mut ws = WebSocketStream::server(stream, Config::default());
    
    while let Some(msg) = ws.next().await {
        match msg.unwrap() {
            Message::Text(text) => ws.send(Message::Text(text)).await.unwrap(),
            Message::Close(_) => break,
            _ => {}
        }
    }
}

Same API works for HTTP/2 and HTTP/3!

Where It's Used

sockudo-ws will power Sockudo, a high-performance Pusher-compatible WebSocket server designed for HFT applications.

Coming soon: N-API bindings for Node.js

Try It Out

[dependencies]
sockudo-ws = { git = "https://github.com/RustNSparks/sockudo-ws" }

# With all features
sockudo-ws = { git = "https://github.com/RustNSparks/sockudo-ws", features = ["full"] }

Full docs and examples: https://github.com/RustNSparks/sockudo-ws


I'd love to hear your feedback, especially from folks working on real-time systems or high-performance networking! Happy to answer questions about the implementation, benchmarks, or future plans.

Edit: Benchmarked on AMD Ryzen 9 7950X, 32GB RAM, Linux 6.18