zerg 0.5.26

dotnet add package zerg --version 0.5.26
                    
NuGet\Install-Package zerg -Version 0.5.26
                    
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="zerg" Version="0.5.26" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="zerg" Version="0.5.26" />
                    
Directory.Packages.props
<PackageReference Include="zerg" />
                    
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 zerg --version 0.5.26
                    
#r "nuget: zerg, 0.5.26"
                    
#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 zerg@0.5.26
                    
#: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=zerg&version=0.5.26
                    
Install as a Cake Addin
#tool nuget:?package=zerg&version=0.5.26
                    
Install as a Cake Tool

NuGet

zerg

Low-level TCP server framework for C# built on Linux io_uring. Direct control over sockets, buffers, and scheduling with no hidden abstractions.

Requirements: Linux kernel 6.1+, .NET 8/9/10.

Install

dotnet add package zerg
dotnet add package zerg.core

Quick Start

using zerg;
using zerg.core;
using zerg.Engine;
using zerg.Engine.Configs;

var engine = new Engine(new EngineOptions { Port = 8080, ReactorCount = 1 });
engine.Listen();

while (engine.ServerRunning)
{
    var connection = await engine.AcceptAsync(CancellationToken.None);
    if (connection is null) continue;
    _ = HandleAsync(connection);
}

static async Task HandleAsync(Connection connection)
{
    while (true)
    {
        var result = await connection.ReadAsync();
        if (result.IsClosed) break;

        var rings = connection.GetAllSnapshotRingsAsUnmanagedMemory(result);
        // process rings.ToReadOnlySequence() ...
        rings.ReturnRingBuffers(connection.Reactor);

        connection.Write("HTTP/1.1 200 OK\r\nContent-Length: 2\r\n\r\nOK"u8);
        await connection.FlushAsync();
        connection.ResetRead();
    }
}

Read API

using zerg.core;

// High-level: get all buffers as a ReadOnlySequence
var result = await connection.ReadAsync();
var rings = connection.GetAllSnapshotRingsAsUnmanagedMemory(result);
ReadOnlySequence<byte> seq = rings.ToReadOnlySequence();
rings.ReturnRingBuffers(connection.Reactor);
connection.ResetRead();

// Low-level: consume one buffer at a time
while (connection.TryGetRing(result.TailSnapshot, out RingItem ring))
{
    ReadOnlySpan<byte> data = ring.AsSpan();
    connection.ReturnRing(ring.BufferId);
}
connection.ResetRead();

Adapters:

using zerg.core;

// Zero-copy PipeReader (buffers held until AdvanceTo)
var reader = new ConnectionPipeReader(connection);
var result = await reader.ReadAsync();
reader.AdvanceTo(consumed, examined);

// BCL Stream (one copy per read)
var stream = new ConnectionStream(connection);
int n = await stream.ReadAsync(buffer);

Write API

connection.Write("data"u8);
await connection.FlushAsync();

// Or via IBufferWriter<byte>
Span<byte> span = connection.GetSpan(256);
connection.Advance(bytesWritten);
await connection.FlushAsync();

Configuration

var engine = new Engine(new EngineOptions
{
    Port = 8080,
    ReactorCount = 4,
    AcceptorConfig = new AcceptorConfig(IPVersion: IPVersion.IPv6DualStack),
    ReactorConfigs = Enumerable.Range(0, 4).Select(_ => new ReactorConfig(
        RecvBufferSize: 32 * 1024,
        BufferRingEntries: 16 * 1024,
        IncrementalBufferConsumption: false  // set true for kernel 6.12+
    )).ToArray()
});

Key ReactorConfig options:

Option Default Description
RingEntries 8192 io_uring SQ/CQ depth
RecvBufferSize 32KB Per-buffer size
BufferRingEntries 16384 Number of pre-allocated recv buffers
BatchCqes 4096 Max CQEs per loop iteration
CqTimeout 1ms Wait timeout (nanoseconds)
IncrementalBufferConsumption false Per-connection buffer rings (kernel 6.12+)

Architecture

One acceptor thread distributes connections round-robin to N reactor threads. Each reactor owns its own io_uring instance, buffer ring, and connection map. No locks on hot paths — all cross-thread coordination uses lock-free MPSC queues.

Key features: multishot accept/recv, provided buffer rings, DEFER_TASKRUN, SINGLE_ISSUER, optional SQPOLL, zero-allocation async via IValueTaskSource, connection pooling.

Examples

dotnet run --project Examples -- raw          # zero-copy ring API
dotnet run --project Examples -- pipereader   # PipeReader adapter
dotnet run --project Examples -- stream       # Stream adapter
dotnet run --project Examples -- sqpoll       # SQPOLL mode

Project Structure

core/           Shared library (utils, ConnectionBase, adapters)
zerg/           Main library (Engine, Reactor, native io_uring shim)
terraform/      Alternative pure-C# io_uring implementation (no native deps)
Examples/       Usage examples
Tests/          End-to-end tests

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.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on zerg:

Package Downloads
dogrider

https://github.com/MDA2AV/zerg

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.5.26 291 4/4/2026
0.5.25 136 3/16/2026
0.5.24 114 3/16/2026
0.5.23 112 3/16/2026
0.5.22 108 3/2/2026
0.4.16 112 2/27/2026
0.4.13 110 2/27/2026
0.4.12 104 2/27/2026
0.4.11 104 2/27/2026
0.3.14 126 2/25/2026
0.3.13 112 2/25/2026
0.3.12 112 2/23/2026