HttpClient.IoUring 1.0.0

dotnet add package HttpClient.IoUring --version 1.0.0
                    
NuGet\Install-Package HttpClient.IoUring -Version 1.0.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="HttpClient.IoUring" Version="1.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="HttpClient.IoUring" Version="1.0.0" />
                    
Directory.Packages.props
<PackageReference Include="HttpClient.IoUring" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add HttpClient.IoUring --version 1.0.0
                    
#r "nuget: HttpClient.IoUring, 1.0.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package HttpClient.IoUring@1.0.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=HttpClient.IoUring&version=1.0.0
                    
Install as a Cake Addin
#tool nuget:?package=HttpClient.IoUring&version=1.0.0
                    
Install as a Cake Tool

HttpClient.IoUring

NuGet License: MIT

A high-performance io_uring transport for SocketsHttpHandler that replaces the default socket I/O with Linux's io_uring interface. Up to 69% faster throughput on Linux.

Performance

On a 2-core VM (AMD EPYC 9V74, Linux 6.17, .NET 10):

Concurrency Socket io_uring Improvement
1 9,339 req/s 15,738 req/s +69%
16 17,412 req/s 22,546 req/s +29%
64 19,553 req/s 24,876 req/s +27%
128 18,649 req/s 27,006 req/s +45%
256 19,435 req/s 26,956 req/s +39%

See BENCHMARKS.md for detailed methodology.

Features

  • Drop-in replacement — one UseIoUring() call replaces the socket transport
  • Batched syscalls — a single io_uring_enter submits CONNECT + SEND + RECV across all connections
  • Zero-copy send (SEND_ZC) for payloads >4KB — avoids kernel buffer copy
  • Registered file descriptors (IOSQE_FIXED_FILE) — kernel skips fd lookup per SQE
  • Async connect via IORING_OP_CONNECT — fully non-blocking connection establishment
  • Full SocketsHttpHandler features — HTTP/1.1, HTTP/2, HTTP/3, TLS, connection pooling, redirects, decompression — all work automatically
  • Targets net8.0, net9.0, net10.0

Requirements

  • Linux with kernel 5.1+ (for io_uring support)
  • Kernel 6.0+ recommended (for zero-copy send, buffer rings)
  • .NET 8 or later

Installation

dotnet add package HttpClient.IoUring

Quick Start

using HttpClient.IoUring.Extensions;

var handler = new SocketsHttpHandler();
using var transport = handler.UseIoUring(options =>
{
    options.RingSize = 256;
});

using var client = new HttpClient(handler);
var response = await client.GetAsync("https://api.example.com/data");

Factory Method

using var handler = IoUringTransport.CreateHandler(options =>
{
    options.RingSize = 256;
});
using var client = new HttpClient(handler);

Architecture

┌─────────────────────────────────────────────────────────────┐
│  HttpClient                                                  │
│   new HttpClient(handler)                                    │
│         │                                                    │
│   SocketsHttpHandler (HTTP/1.1+2+3, pooling, TLS, etc.)     │
│    └── ConnectCallback = IoUringTransport.ConnectAsync        │
│              │                                                │
│         IoUringTransport                                     │
│          ├── IoUringConnector (IORING_OP_CONNECT + DNS)      │
│          ├── IoUringStream (RECV/SEND via io_uring)           │
│          └── IoUringClientLoop (shared Ring, IO thread)       │
│               └── Ring → SQ/CQ → io_uring_enter              │
└─────────────────────────────────────────────────────────────┘

How it works

All IoUringStream instances share a single io_uring Ring. When multiple connections read/write concurrently, their SQEs are batched into a single io_uring_enter syscall:

Thread A: conn1.ReadAsync()  → enqueue RECV SQE
Thread B: conn2.WriteAsync() → enqueue SEND SQE
Thread C: conn3.Connect()    → enqueue CONNECT SQE
                                    │
IO Thread: io_uring_enter(3 SQEs) ←─┘  ← one syscall for 3 operations

Configuration

Option Default Description
RingSize 256 SQ/CQ ring depth (power of two)
ConnectTimeout 30s TCP connect timeout
EnableZeroCopySend false Use SEND_ZC for large payloads
ZeroCopySendThreshold 4096 Minimum payload size for zero-copy
MaxRegisteredFiles 256 Registered fd table size (0 to disable)

io_uring Features Used

Feature Kernel Purpose
IORING_OP_CONNECT 5.1+ Async TCP connect
IORING_OP_RECV 5.1+ Receive response data
IORING_OP_SEND 5.1+ Send request data
IORING_OP_SEND_ZC 6.0+ Zero-copy send (opt-in)
IORING_OP_CLOSE 5.6+ Async close
IORING_REGISTER_FILES 5.1+ Registered file descriptors

Project Structure

├── src/HttpClient.IoUring/         ← NuGet library (net8.0/net9.0/net10.0)
├── tests/HttpClient.IoUring.Tests/ ← xunit tests
├── benchmarks/                      ← BenchmarkDotNet comparisons
└── samples/SampleApp/               ← Minimal usage example

License

MIT

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net10.0

    • No dependencies.
  • net8.0

    • No dependencies.
  • net9.0

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.0 103 3/20/2026

v1.0.0 — Initial release
• Drop-in io_uring transport via handler.UseIoUring()
• Batched syscalls across all connections (single io_uring_enter)
• Buffer rings for recv (eliminates per-recv memory pinning)
• SEND_ZC zero-copy send for large payloads (opt-in)
• Registered file descriptors (IOSQE_FIXED_FILE)
• Lock-free CompletionSlots for O(1) CQE dispatch
• 27–69% faster than default SocketsHttpHandler
• Targets net8.0, net9.0, net10.0