SocketSet.Garnet 0.1.196-alpha

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

SocketSet

High-performance, low-allocation socket hosting for .NET.

SocketSet is a sharded socket engine that puts your callbacks as close to the kernel's completion notification as the platform allows. It picks the best available backend for the host and presents a single API over all of them:

Backend Platform Notes
SocketSetFactory.IoUring Linux (5.x+, with the required features) thread-per-shard, multishot accept, provided buffers, zero-copy send
SocketSetFactory.Epoll Linux readiness-driven fallback for kernels without the io_uring features; zero-copy writev send, full TLS/kTLS support
SocketSetFactory.WindowsIocp Windows raw Winsock + IOCP, bypassing managed sockets
SocketSetFactory.WindowsRio Windows Registered I/O; TCP-only, opt-in, latency-focused
SocketSetFactory.Managed anywhere portable SocketAsyncEventArgs fallback

SocketSetFactory.Default probes the host and chooses for you (IOCP on Windows; io_uring on a capable Linux kernel, epoll otherwise; the managed fallback elsewhere), so the same binary runs everywhere and simply goes faster where the platform lets it.

Supported frameworks: net10.0 and net472. (The native backends are .NET-only; .NET Framework gets the managed fallback.)

Working on SocketSet?

Start with AGENTS.md — it points at the backlog (TODO.md), the measurements of record (AspNetDemo/RESULTS.md) and the benchmarking rules (bench/README.md), and lists the house rules for producing a number anyone should believe. If you are picking this up on Windows, TODO.md opens with a section written for you.

Installation

dotnet add package SocketSet

Two companion packages host existing servers on the transport, and ship alongside it:

  • SocketSet.AspNetCore — a Kestrel connection transport: builder.UseSocketSet(...), with optional transport-terminated TLS (including kTLS on Linux).
  • SocketSet.Garnet — hosts Garnet on the SocketSet transport via its pluggable IGarnetServer seam.

All three are currently published as -alpha: this is pre-alpha code and every API is free to change.

Usage

Derive from SocketSet and override the callbacks you care about. Buffers are handed to you as Span<byte> over memory the engine owns — you never allocate on the IO path, and you reply by writing into the response buffer rather than by handing back an array.

using SocketSets;
using System.Net;

sealed class EchoServer(SocketSetOptions options) : SocketSet(options)
{
    protected override void OnReceive(ref ReceiveContext ctx)
    {
        if (ctx.IsEof) return; // peer closed

        // the payload is already sitting in RawBuffer; reply in-place by saying how much
        // of that buffer to send back (mutate RawBuffer first if the response differs)
        ctx.ResponseBytes = ctx.PayloadBytes;
    }
}

using var server = new EchoServer(new SocketSetOptions { Shards = 4 });
server.Listen(new IPEndPoint(IPAddress.Any, 10000));
Console.ReadLine();

Outbound connections use the same type; OnConnect fires when the handshake completes, and OnReceive handles the replies:

server.Connect(new IPEndPoint(IPAddress.Loopback, 10000));

To write from outside the IO callback (a background worker, a timer, a different connection's callback), use the Connection handed to you — Send marshals onto the owning IO context and serializes with the connection's other writes:

connection.Send(payload); // safe from any thread

Connection also implements IBufferWriter<byte>, so GetSpan/Advance/Flush works for incremental composition.

Unix domain sockets are supported on all backends (UnixDomainSocketEndPoint, including the Linux abstract namespace via a leading @), and an already-bound listener can be adopted by handle with ListenHandle for socket-activation scenarios.

TLS

TLS is terminated in the transport, not in a stream wrapper above it: set a TlsProvider on the options and the handshake, record framing and encrypt/decrypt happen on the engine's own buffers, with your callbacks seeing plaintext. OpenSSL backs Linux (and can hand the record layer to the kernel — kTLS — where the OpenSSL build and kernel support it, probed at runtime and reported rather than assumed); SChannel backs Windows. TLS 1.3 is the default floor on both, and servers refuse client-initiated renegotiation.

var options = new SocketSetOptions
{
    Tls = new OpenSslTlsProvider(certPem, keyPem),   // or SChannelTlsProvider on Windows
    TlsMode = TlsMode.Both,                          // or Accept / Connect for proxy shapes
};

TlsMode makes the provider directional: Accept for a TLS-terminating proxy (TLS in, plaintext out), Connect for a TLS-originating one (plaintext in, TLS out) — a direction that is off behaves exactly as if no provider were configured.

Configuration

SocketSetOptions controls sharding and the pre-allocated, pre-pinned buffer pools:

var options = new SocketSetOptions
{
    Shards = Environment.ProcessorCount / 2,
    SocketsPerShard = 4096,
    PinWorkerThreads = true,
    Factory = SocketSetFactory.Default,
};

Everything is sized up front: read buffers, write buffers, and connection slots are allocated per shard when the set is constructed, so steady-state operation does not allocate. See the XML docs on SocketSetOptions for the individual knobs and which backends honour them.

License

MIT

Product Compatible and additional computed target framework versions.
.NET 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

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
0.1.196-alpha 54 8/3/2026