What is Nalix?
Nalix is a low-latency binary realtime networking framework for .NET 10, aimed at Blazor WebAssembly, MAUI and game servers. You define packets as C# classes, write handlers keyed by opcode, and exchange data over TCP, UDP or WebSocket from the Nalix client SDK with no HTTP layer in between (Nalix README).
Nalix is open source under Apache-2.0, created and maintained by Phan Phúc Nguyên (the author of this article) at ppn-systems/nalix. Because the writer is also the project's author, every figure here comes from the project's public documentation and is labelled as self-published.
When you need a dedicated C# networking library instead of SignalR or gRPC
Most .NET applications should use the familiar options: ASP.NET Core, SignalR or gRPC. They are mature, well documented, have clients in many languages and work through existing HTTP infrastructure. Nalix targets a narrower set of problems: game servers and realtime apps where many small packets flow continuously and per-packet latency and server-side allocations matter.
In that niche, three things tend to cost the most: the HTTP protocol layer, general-purpose serialization formats, and per-message allocations that pressure the garbage collector. Nalix chooses its own binary framing, compile-time generated serializers, and a hot path built on pooled buffers and reusable packets.
If you are still comparing general approaches (TCP, UDP or WebSocket, framing, tick rate) rather than a specific library, read our neutral guide to networking for game servers and realtime systems in C# first.
| Criterion | Nalix | SignalR | gRPC (.NET) | MagicOnion |
|---|---|---|---|---|
| Wire format | Custom binary frames, source-generated serializers | JSON or MessagePack over HTTP | Protobuf over HTTP/2 | MessagePack over gRPC (HTTP/2) |
| Encryption | Built in: X25519 handshake, server key pinning, ChaCha20-Poly1305 per packet | TLS (HTTPS) | TLS | TLS |
| Transports | TCP, UDP, WebSocket | WebSocket, SSE, long polling | HTTP/2 (HTTP/3) | HTTP/2 |
| Native AOT | Yes | Partial | Yes | Via source generator |
| Blazor WASM client | Yes, over WebSocket | Yes | gRPC-Web only | No |
Design: layered architecture and the packet model
Nalix ships as layered NuGet packages; each depends only on lower levels with no circular references, so you install only the layers you need (Nalix README).
- Level 0 – Nalix.Abstractions: contracts and enums, zero dependencies.
- Level 1 – Nalix.Environment: low-level IO primitives, buffer leasing.
- Level 2 – Nalix.Codec (framing, crypto, serialization) and Nalix.Framework (identity, DI, task orchestration).
- Level 3 – Nalix.Network (TCP/UDP, sessions), Nalix.Runtime (dispatch, middleware, throttling), Nalix.SDK (client sessions).
- Level 4 – Nalix.Hosting: Microsoft-style host and builder APIs.
Packets are C# classes with attributes and opcodes
Each packet is a C# class marked with the Packet and GenerateFormatter attributes, declaring a static opcode (0x7001 in the HelloWorld sample) and field order via SerializeOrder. On the server, handlers are methods carrying a PacketOpcode attribute; Nalix routes each packet to its handler by opcode.
Source generators and Roslyn analyzers
Serializers are generated at compile time rather than using runtime reflection. Nalix.Analyzers contains Roslyn analyzers, code fixes and source generators (packed into Nalix.Abstractions) that catch packet-definition mistakes at build time. This is also what keeps every package trimmable and Native AOT-compatible.
Reducing allocations
The README describes a hot path using pooled buffers and pooled packets. In the HelloWorld sample, the handler rents its response packet from PacketFactory and returns it when done, so repeated calls do not allocate new packets. The project targets .NET 10 and C# 14 to use Span, ref struct and static abstract interface members for opcodes and formatters. This reduces allocations rather than eliminating them: the project's own benchmark still measures 56 bytes per message on the server.
Transports and middleware
TCP, UDP and WebSocket share one packet model. The SecureMultiTransportHelloWorld sample runs all three under one secure session, including authenticated UDP. Browsers connect through Blazor WebAssembly over WebSocket. The server includes middleware for permissions, rate limiting, timeouts and traffic shaping, and you can add your own.
Security: X25519, server key pinning, ChaCha20-Poly1305 and session resume
Nalix builds encryption into its protocol and needs no TLS certificates. In plain terms:
- X25519 (RFC 7748): a Diffie-Hellman key exchange on Curve25519 at roughly the 128-bit security level. Both sides derive a shared secret without sending it over the network (RFC 7748).
- Server key pinning: the client knows the server's public key in advance, so a man-in-the-middle presenting a different key fails the handshake. This authenticates the server instead of a certificate.
- ChaCha20-Poly1305 (RFC 8439): an authenticated encryption (AEAD) algorithm that keeps content secret and detects tampering. Nalix applies it per packet (RFC 8439).
- Session resume: after a disconnect, the client resumes with a session token instead of a full new handshake.
Trade-offs to know
RFC 8439 requires that a nonce never repeats under the same key; any custom AEAD-based protocol must get this right. A custom protocol also lacks TLS's breadth of real-world scrutiny. If your organisation mandates TLS or inspects HTTPS traffic, weigh this carefully. The project's vulnerability reporting policy is in SECURITY.md.
Benchmarks: reading the self-published numbers correctly
All figures below are a self-published loopback benchmark run by the project on a 4 vCPU machine: Ubuntu 24.04, Intel Xeon 2.10 GHz, .NET 10 (SDK 10.0.401), Release, median of 3 runs, 32-byte payload; each framework uses its own client. Raw data is in the network-comparison document.
| Library | p50 (µs) | p99 (µs) | ops/s, 64 clients | Server alloc/msg (B) | Server CPU/msg (µs) |
|---|---|---|---|---|---|
| Nalix TCP | 52.2 | 154.9 | 74,791 | 56 | 29.3 |
| Nalix WebSocket | 55.5 | 159.6 | 69,135 | 192 | 27.1 |
| SignalR (WebSocket, MessagePack) | 76.3 | 190.8 | 71,871 | 672 | 21.8 |
| gRPC bidi stream (h2c) | 68.4 | 167.3 | 77,648 | 264 | 21.9 |
| MagicOnion StreamingHub | 74.2 | 173.8 | 67,501 | 200 | 26.3 |
| Nalix TCP + X25519/ChaCha20-Poly1305 | 57.6 | 154.3 | 63,309 | 56 | 34.2 |
| gRPC bidi stream + TLS | 100.4 | 282.6 | 57,791 | 812 | 30.4 |
How to read the results
- Nalix has the lowest single-client p50 and server allocation per message among the full frameworks measured; a hand-written raw socket (30.9 µs) and a raw Kestrel WebSocket echo (45.0 µs) are still faster.
- On 64-client throughput, gRPC bidi stream is higher at 32 bytes; at 1 KB, SignalR and gRPC are higher than Nalix. SignalR and gRPC also use less server CPU per message.
- The README states its own caveats: loopback, with load generator and server sharing the same cores, so capacity on bare metal with dedicated network hardware will differ; encrypted rows compare per-packet AEAD with TLS stream transport.
- Run the benchmark on your own hardware and workload before deciding.
When NOT to use Nalix
The project README lists cases where other tools fit better:
- You need HTTP/REST interop, proxies or API gateways that understand HTTP: use gRPC or ASP.NET Core.
- You have polyglot clients (JavaScript, Go, Python, Java): Nalix only has a .NET client SDK; gRPC and SignalR have clients for many languages.
- You are on .NET 8/9 or .NET Framework: Nalix targets .NET 10 only.
- You are building a Unity client: Unity does not run .NET 10, so the SDK cannot be used there today; MagicOnion supports Unity.
An extra note from the author
Beyond that list, if your team does not yet need to measure latency in microseconds, the cost of learning and operating a custom protocol is usually not worth it. SignalR and gRPC are the safer default for most business applications.
Getting started with Nalix
If you are building .NET backends for AI systems, see building an AI backend with C# and .NET.
- Install the .NET 10 SDK and use C# 14.
- Add Nalix.Hosting for the server and Nalix.SDK for the client; analyzers and source generators come with Nalix.Abstractions.
- Run samples/HelloWorld: start HelloWorld.Server with dotnet run, then HelloWorld.Client in a second terminal.
- To encrypt: call UseSecureConnections on the server builder and HandshakeAsync after the client connects (see SecureMultiTransportHelloWorld).
- Explore the ChatRoom (server push) and BlazorWasm (browser client) samples.
Frequently asked questions
Is Nalix free?
Yes. Nalix is open source under the Apache License 2.0, which permits commercial use under the licence's conditions.
Can Nalix replace SignalR or gRPC?
Not in every case. Nalix fits when clients are .NET 10 and low latency and allocations matter. If you need HTTP, polyglot clients or Unity, SignalR, gRPC or MagicOnion fit better.
Does Nalix support Unity?
Not today. Unity does not run .NET 10, so the Nalix SDK cannot be used there; the README suggests MagicOnion for that case.
Why doesn't Nalix use TLS, and how does it encrypt instead?
Nalix builds in an X25519 handshake with server key pinning and per-packet ChaCha20-Poly1305 encryption, so no certificates are needed. The trade-off is a custom protocol, which matters if your organisation mandates TLS.
Can I trust the Nalix benchmarks?
They are a self-published loopback benchmark on a 4 vCPU machine, with raw data and stated caveats. Treat them as a reference point and measure in your own environment.