nexus-net
Low-latency network protocol primitives. Sans-IO. Zero-copy where possible. Framework-agnostic — works with mio, io_uring, tokio, or raw syscalls.
Performance
7-14x faster than tungstenite for WebSocket frame parsing. 1.5x faster end-to-end over TLS with JSON deserialization.
| Path | nexus-net | tungstenite | Speedup |
|---|---|---|---|
| ws:// text 128B parse | 38 cycles | 497 cycles | 13x |
| ws:// binary 128B parse | 34 cycles | 467 cycles | 14x |
| ws:// throughput (batch) | 26 cycles/msg | 182 cycles/msg | 7x |
| wss:// 77B JSON quote tick | 185ns, 5.4M/s | 281ns, 3.6M/s | 1.5x |
| TCP loopback 40B binary | 24ns, 42M/s | 68ns, 15M/s | 2.8x |
At 3GHz: 38 cycles = 12.7ns per message. 26 cycles batched = ~115M msg/sec.
517/517 Autobahn conformance tests passed (0 failed, 216 unimplemented compression — intentionally unsupported).
Architecture
Application
^ Message<'a> / OwnedMessage
FrameReader / FrameWriter (ws, sans-IO)
^ plaintext bytes
TlsCodec (optional, feature-gated)
^ encrypted bytes
I/O (your choice)
Each layer is a pure state machine. No syscalls, no sockets, no async.
Bytes in, messages out. The I/O layer is yours — mio, io_uring, tokio,
raw libc::read, kernel bypass.
Quick Start
# ws:// only (no TLS dependency)
= "0.1"
# ws:// + wss:// (TLS via rustls)
= { = "0.1", = ["tls"] }
# Everything
= { = "0.1", = ["full"] }
WebSocket Client (ws://)
use ;
let mut ws = connect?;
ws.send_text?;
loop
WebSocket Client (wss://)
use WsStream;
// TLS detected from wss:// scheme — automatic with system root certs
let mut ws = connect?;
// Same API — recv(), send_text(), send_binary(), etc.
Or with custom TLS config:
use WsStream;
use TlsConfig;
let tls = builder.tls13_only.build?;
let mut ws = builder
.tls
.disable_nagle
.connect?;
Sans-IO (decoupled from sockets)
use ;
let = pair;
// You own the I/O — feed bytes however you want
reader.read_from?;
// Drain messages with poll limit
for _ in 0..8
Send Path (borrow, don't own)
let order = serialize_order; // you own this
ws.send_text?; // we borrow
archive.write?; // still yours — archive after send
Modules
buf — Buffer Primitives
ReadBuf— flat byte slab for inbound parsing. Pre/post padding. Pointer advancement, auto-reset when empty.WriteBuf— headroom buffer for outbound framing. Payload appended, protocol headers prepended. One contiguous slice for the syscall.
ws — WebSocket (RFC 6455)
FrameReader— sans-IO inbound parser. Handles frame parsing, fragment assembly, control frame interleaving, SIMD masking, UTF-8 validation. ReturnsMessage<'a>(zero-copy borrowed) orOwnedMessage.FrameWriter— sans-IO outbound encoder. Encodes into&mut [u8]orWriteBuf.WsStream<S>— convenience I/O wrapper over anyRead + Write. HTTP upgrade handshake built in.WsTlsStream<S>— same asWsStreambut with TLS. Requirestlsfeature.Message<'a>—Text(&str),Binary(&[u8]),Ping(&[u8]),Pong(&[u8]),Close(CloseFrame). Text is validated UTF-8. Close codes are parsed intoCloseCodeenum.
http — HTTP/1.1 (minimal)
RequestReader/ResponseReader— sans-IO HTTP parsers backed byhttparse(SIMD-accelerated). Zero-copy header access.write_request/write_response— zero-alloc HTTP construction.
tls — TLS (feature: tls)
TlsConfig— shared config (Arc<ClientConfig>). System root certs, custom certs,danger_no_verify(), TLS 1.3 only.TlsCodec— sans-IO decrypt/encrypt wrapping rustls.process_into(&mut FrameReader)feeds decrypted plaintext directly into the WS parser.
Features
| Feature | Default | Description |
|---|---|---|
tls |
No | TLS support via rustls + aws-lc-rs |
socket-opts |
No | Socket options (SO_RCVBUF, SO_SNDBUF) via socket2 |
full |
No | All features enabled |
Without features: zero TLS compile time. The ws and http
modules work standalone.
Design Decisions
Zero-copy inbound. Message::Text(&str) borrows from the reader's
internal buffer. No heap allocation per message. Drop the message,
call recv() again.
Borrow, don't own. Send APIs take &str / &[u8]. You keep
ownership for archival after send. Works across .await points.
Sans-IO. Protocol logic is a pure state machine. The same
FrameReader works with blocking sockets, mio, io_uring, tokio, or
kernel bypass. No runtime coupling.
SIMD-accelerated. XOR masking uses SSE2/AVX2. UTF-8 validation
uses simdutf8. HTTP header parsing uses httparse (SIMD vectorized).
No permessage-deflate. WebSocket compression adds latency and no crypto exchange uses it. Exchanges that compress use application-level gzip (e.g., OKX sends gzipped binary frames).
Layered, not coupled. ReadBuf → FrameReader → WsStream are
independent layers. Use any combination. TlsCodec slots between
socket and FrameReader without changing either.
Testing
# Autobahn conformance (requires Podman)
# wss:// echo test (requires network)
# Benchmarks