Skip to content

Repository files navigation

ioxide

nuget license net linux

A shared-nothing io_uring runtime for .NET.

One ring per reactor thread, one reactor per core. Each reactor owns its ring, its SO_REUSEPORT listener, its connections and its clients outright, so nothing is shared and nothing is locked - a request never leaves the core it arrived on, inbound and outbound alike. What makes that practical in .NET is that you do not give up the platform's async model to get it: handlers are ordinary async Task code, ring completions resume their continuations inline on the reactor thread, and a per-reactor SynchronizationContext catches everything that would otherwise escape - timers, HttpClient, Task.Run. You always wake up on your reactor, so connection, pool and handler state stays single-threaded without a lock in sight.

ioxide hands you raw bytes and stays out of HTTP; when you want a framework on top, ioxide.Kestrel swaps the transport under an existing ASP.NET Core app with your endpoints unchanged.

Linux 6.1+ · .NET 10 / .NET 11 · 0.4.153 - experimental

Documentation - architecture, guides, and every example as runnable code side by side.

Packages

Every package shares one version and depends only on the runtime. Start with ioxide - reactors, TCP/UDP transports, connections, the ring-native client seam, and TLS termination (OpenSSL handshake over the ring, then kTLS, so handlers keep writing plaintext) - then add exactly what you use.

Protocols. HTTP/2 and HTTP/3 each come twice: a bundled native, or the same surface in pure C#.

Package What it does
ioxide.ngtcp2 QUIC. ngtcp2 + picotls as one bundled native; only system dependency is OpenSSL 3.
ioxide.nghttp3 HTTP/3 + QPACK (nghttp3), bundled native. Rides any QUIC connection.
ioxide.http3 HTTP/3 in pure C# - frames, QPACK, Huffman. Zero native code, drop-in for ioxide.nghttp3.
ioxide.nghttp2 HTTP/2 (nghttp2), bundled native. h2c, or h2 over TLS via ALPN.
ioxide.http2 HTTP/2 in pure C# - framing, HPACK, flow control. Zero native code, drop-in for ioxide.nghttp2.

Clients. One pool per reactor, opened on the reactor thread, so every call rides the ring that accepted the request.

Package What it does
ioxide.httpclient HTTP/1.1, HTTP/2 and HTTP/3 behind one API, protocol chosen per origin via Alt-Svc, with client-side TLS for https://.
ioxide.pg Postgres. Connect, query and stream rows on the owning ring.
ioxide.redis Redis. RESP2, pipelining, pub/sub.
ioxide.file Static assets. Immutable snapshots, baked responses, positional ring reads.

Serving.

Package What it does
ioxide.Kestrel ASP.NET Core transport: UseIoxide() and Kestrel runs one ring per core, its request loop pinned to the reactor thread.

Where the code is

Nothing here is pseudocode. Every pattern above exists as something you can run:

What you get
Documentation The examples browser - TCP with and without kTLS, HTTP/2, QUIC, HTTP/3, every client, and all nine proxy combinations, side by side.
Playground One project per workload, grouped by topic. Each Program.cs is a complete server - config, reactors, threads, handler - so you can copy the file out and run it.
Examples.AspNet UseIoxide() measured against a stock Kestrel baseline.

About

The shared-nothing io_uring runtime for .NET

Resources

Stars

41 stars

Watchers

4 watching

Forks

Releases

Packages

Used by

Contributors

Languages