You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
A header-only C++20 WebSocket library built directly on Linux io_uring and kTLS.
Signet_io_uring is a low-latency WebSocket client library aimed at workloads
where every microsecond on the wire matters: high-frequency trading market
data feeds, real-time pub/sub fan-out, financial telemetry, and exchange
order ingest. It does not wrap an event loop. It does not sit on top of
Boost.Asio. It talks to the Linux kernel through io_uring directly, hands
TLS off to the kernel via kTLS when the cipher suite allows, and walks
the WebSocket frame layer in-place over registered, page-aligned buffers.
Field
Value
Status
v0.1.0-alpha — API may change, security audit complete
License
Apache 2.0
Standard
C++20, header-only
Platform
Linux ≥ 5.15 (x86_64; AArch64 best-effort)
Tests
302 unit tests across 13 files, all passing (2 network-dependent integration tests disabled)
Audit
47 issues found, all critical/high/medium fixed (docs/SECURITY_AUDIT.md)
Most C++ WebSocket libraries are written against epoll or Boost.Asio.
That's fine for most applications — but it leaves a few microseconds on
the floor that an HFT-grade market data path cannot afford:
Syscall amortization. Every Asio read is a read() syscall. Every
Signet_io_uring read is an SQE submitted to a shared ring; the kernel
drains a batch at a time without crossing the user/kernel boundary per
message.
Zero-copy framing. Frames are parsed in-place over a registered
fixed-buffer pool. The bytes the kernel wrote into your page are the
same bytes the WebSocket parser reads — no memcpy, no per-frame
allocation.
kTLS hand-off. After the OpenSSL handshake, the cipher state is
pushed into the kernel via setsockopt(TCP_ULP, "tls"). From that
point on, plaintext writes go to the socket directly and the kernel
handles encryption — no userspace SSL_write loop, no double-buffering.
SIMD masking + UTF-8. XOR-mask and UTF-8 streaming validators
unroll over AVX2 / SSE4.2 when the build host supports them.
Lock-free buffer pool. A bounded SPSC free-list backs the fixed
buffers, so the hot path never touches a mutex.
If your application makes <1k WebSocket connections and processes
<10k messages/s per connection, you do not need this library —
use a higher-level abstraction. Signet_io_uring exists for the cases
where you do.
Requirements
Component
Minimum
Notes
Linux kernel
5.15
for io_uring features and kTLS upper layer protocol
Compiler
GCC 11+ or Clang 14+
-std=c++20 required
liburing
2.0+
pkg-config liburing
OpenSSL
3.0+
TLS 1.2 / 1.3, kTLS-capable cipher suites
zlib
1.2+
for permessage-deflate (optional but on by default)
#include<signet/ws/ws_client.hpp>
#include<iostream>intmain() {
auto tls = signet::TlsContext::create_client().value();
auto ws = signet::connect_websocket("wss://echo.websocket.org/", tls).value();
(void)ws.send_text("hello");
auto msg = ws.read_message().value();
if (msg) std::cout << msg->as_string() << '\n';
}
Note on naming. The product name is Signet_io_uring, but for
source-compatibility reasons the include path stays <signet/...> and the
C++ namespace stays signet::. The CMake target is
signet_io_uring::signet_io_uring (with signet::signet retained as a
legacy alias).
Microbenchmarks live under benchmarks/bench_ws.cpp and are built with
-DSIGNET_BUILD_BENCHMARKS=ON. The numbers below were captured on
2026-04-09 against v0.1.0-alpha on a deliberately modest 4-core
1.9 GHz x86_64 VM (no AVX2, 32 KiB L1d, 256 KiB L2, 6 MiB L3) running
under WSL2. Production hardware with AVX2 and wider L2/L3 caches
typically runs 2–4× faster — these are the floor, not the ceiling.