· via dev.to (home feed)
.NET 11 adds built-in Zstandard compression streams and HttpClient zstd support
.NET 11's RC 2 adds ZstandardStream, span-based codecs, dictionary training and HttpClient zstd support inside the shared framework, removing the need for third-party zstd NuGet packages.

.NET 11 brings Zstandard (zstd) compression into the base class library, so applications no longer need a third-party NuGet wrapper to read or write the format. According to a dev.to write-up, the new APIs live in System.IO.Compression, ship inside the shared framework with no package references, and sit alongside the existing GZipStream and BrotliStream. The runtime is currently at Release Candidate 2, which carries a go-live licence for production use, but general availability has not arrived yet.
What the new API surface covers
The dev.to post lists five new compression types. ZstandardStream is a Stream that behaves the same way GZipStream does, so existing code often needs nothing more than a class-name swap. ZstandardEncoder and ZstandardDecoder operate on spans for callers that do not want a stream abstraction. ZstandardDictionary trains a compression dictionary from sample payloads, and ZstandardCompressionOptions exposes quality (ranging from -131072 to 22, with a default of 3), window size, checksums and long-distance matching. On the networking side, DecompressionMethods.Zstandard enables automatic response decompression, while ZstandardCompressedContent compresses outgoing request bodies and sets Content-Encoding: zstd.
Compression and speed numbers
Running the .NET 11 RC 1 SDK, the author compressed a synthetic log file — 2,000 lines of fake JSON totalling 188,010 bytes — 200 times at CompressionLevel.Optimal. GZip produced 13,499 bytes in 218 ms, Brotli 11,936 bytes in 299 ms, and Zstandard 11,891 bytes in 150 ms, making it both the smallest and the fastest of the three built-in compressors. The author stresses that the payload is highly repetitive and the test ran on a single machine, so the figures are indicative rather than a benchmark; the post points to the .NET team's own Canterbury Corpus results in the Preview 1 libraries release notes. Raising quality to 19 with an appended checksum brought the same file down to 7,535 bytes.
Dictionaries fix small payloads
Individual small messages barely compress because the repetition lies between messages, not inside them. The author trained a 4,096-byte ZstandardDictionary on 1,000 "order.created" events, then compressed 200 events the dictionary had never seen. Raw messages averaged 152.2 bytes; plain zstd managed only 134.7; with the dictionary the average fell to 38.6 bytes. That gap, the post argues, is what turns compression from not worth it into an obvious win for event queues and similar small-message workloads.
HttpClient integration
One flag — setting AutomaticDecompression to include DecompressionMethods.Zstandard — makes HttpClient advertise gzip and zstd in Accept-Encoding and decode responses transparently. The author's local test server answered a request for 8,000 bytes of JSON with 33 bytes of zstd, and GetStringAsync still returned the full text. In the other direction, wrapping a StringContent in ZstandardCompressedContent delivered 300 copies of a small JSON object to the test server as 36 bytes on the wire, though the post warns to confirm the server actually accepts zstd request bodies before enabling it.
Sharp edges to watch
The write-up flags four gotchas. The integer parameter after the dictionary in TryCompress is windowLog2, not quality, and values below 10 throw an ArgumentOutOfRangeException — the safe value is ZstandardCompressionOptions.DefaultWindowLog2 (23). Decompressing dictionary-compressed data without the matching dictionary fails silently: TryDecompress simply returns false, so dictionaries need versioning and an identifier shipped alongside messages. A default HttpClient sends no Accept-Encoding header at all, so if a server compresses anyway the client receives raw zstd bytes rather than JSON. Finally, sample code from the preview era is already stale: WindowLog was renamed to WindowLog2, MinWindowLog2 and MaxWindowLog2 in the RC, so the API docs outrank older blog snippets. For upstream detail, the post links Microsoft Learn's "What's new in .NET 11 libraries" page and dotnet/runtime issues #119575 and #123531.
Why it matters
zstd has become a common denominator in log pipelines, databases and HTTP content negotiation, but .NET developers previously had to choose a third-party wrapper, verify that its native binaries existed for every target platform, and hope it stayed maintained — the kind of dependency that resurfaces in every security review. Making zstd a first-class Stream mirrors the gzip and Brotli experience and keeps migration cost close to zero. Dictionary support extends compression to small-message scenarios where it previously failed to pay off, and the HttpClient hooks prepare .NET clients for servers that already speak zstd. Once .NET 11 reaches general availability, an entire category of NuGet dependencies can simply be deleted.
- #dotnet
- #zstandard
- #compression
- #net-11
- #http-client