Skip to content

Choosing a Codec

compressionz supports seven compression codecs. This guide helps you choose the right one.

ScenarioRecommendedWhy
General purposecz.zstdBest balance of speed and ratio
Maximum speedcz.lz4.block36+ GB/s, requires size tracking
Real-time / messagingcz.snappyFast, self-describing format
HTTP / webcz.gzipUniversal browser support
Static assetscz.brotliBest ratio for one-time compression
File storagecz.lz4.frameSelf-describing with checksums
CodecCompressDecompressRatioMemory
LZ4 Block36.6 GB/s8.1 GB/s99.5%~input
Snappy31.6 GB/s9.2 GB/s95.3%~input
Zstd12.0 GB/s11.6 GB/s99.9%~input
LZ4 Frame4.8 GB/s3.8 GB/s99.3%~input
Gzip2.4 GB/s2.4 GB/s99.2%~3x input
Brotli1.3 GB/s1.9 GB/s99.9%~2x input
CodecStreamingDictionaryChecksumAuto-DetectSelf-Describing
zstdYesYesYesYesYes
lz4.frameYesNoYesYesYes
lz4.blockNoNoNoNoNo
snappyNoNoNoYesYes
gzipYesNoYesYesYes
brotliYesNoNoNoNo
zlibYesYesYesYesYes

Use Zstd when: You need excellent compression ratio with high speed.

const compressed = try cz.zstd.compress(data, allocator, .{});
  • Exceptional compression ratio (99.9% on repetitive data)
  • Very fast decompression (11+ GB/s)
  • Fast compression at default level (12 GB/s)
  • Supports dictionary compression
  • Built-in content checksums
  • Slightly slower than LZ4/Snappy for compression
  • Larger compressed headers than raw formats
  • General-purpose compression
  • Databases and data stores
  • Log file compression
  • Network protocols
  • Anything that doesn’t have a specific requirement
// Fastest - 12 GB/s
try cz.zstd.compress(data, allocator, .{ .level = .fast });
// Best ratio - 1.3 GB/s but maximum compression
try cz.zstd.compress(data, allocator, .{ .level = .best });
LevelCompressDecompressNotes
fast12.2 GB/s11.4 GB/sRecommended for speed
default12.0 GB/s11.6 GB/sBest balance
best1.3 GB/s12.1 GB/sUse for archival

LZ4 comes in two variants: frame (self-describing) and block (raw only).

Use LZ4 Frame when: You need fast, checksummed compression with streaming support.

const compressed = try cz.lz4.frame.compress(data, allocator, .{});
const decompressed = try cz.lz4.frame.decompress(compressed, allocator, .{});
  • Self-describing format
  • Built-in content checksums
  • Streaming support
  • ~4.8 GB/s throughput

Use LZ4 Block when: You need absolute maximum speed and control both ends.

const compressed = try cz.lz4.block.compress(data, allocator);
// Must provide original_len for decompression!
const decompressed = try cz.lz4.block.decompressWithSize(compressed, original_len, allocator);
  • 36+ GB/s compression
  • 8+ GB/s decompression
  • No framing overhead
  • Requires tracking original size externally
  • In-memory caching
  • IPC / message passing
  • Game asset compression
  • Real-time data pipelines

Use Snappy when: You need very fast compression with a self-describing format.

// Snappy has no options
const compressed = try cz.snappy.compress(data, allocator);
  • Very fast (31+ GB/s compression)
  • Self-describing format
  • Simple block format
  • Pure Zig implementation with SIMD
  • Lower compression ratio (95.3%)
  • No streaming support
  • No dictionary support
  • Real-time applications
  • Message queues
  • Caching systems
  • Situations where decompression speed > ratio

Use Gzip when: You need compatibility with existing tools and systems.

const compressed = try cz.gzip.compress(data, allocator, .{});
  • Universal support (browsers, servers, CLI tools)
  • Good compression ratio
  • Built-in CRC32 checksum
  • Streaming support
  • Slower than modern alternatives
  • Higher memory for decompression (2-3x)
  • No dictionary support
  • HTTP Content-Encoding
  • Cross-platform file exchange
  • Compatibility with existing .gz files
  • When recipients may use other tools

Use Brotli when: Compression ratio matters more than speed.

const compressed = try cz.brotli.compress(data, allocator, .{
.level = .best,
});
  • Highest compression ratios
  • Good decompression speed (1.5-2 GB/s)
  • Optimized for text/web content
  • Supported by all modern browsers
  • Slow compression at high levels
  • Higher memory usage
  • No magic bytes (can’t auto-detect)
  • Static web assets (CSS, JS, HTML)
  • CDN content
  • One-time compress, many decompress scenarios
  • When storage/bandwidth cost matters
LevelCompressRatioUse Case
fast1.3 GB/s99.9%Dynamic content
default1.3 GB/s99.9%General use
best86 MB/s99.9%+Static assets

Use Zlib when: You need deflate with headers and Adler-32 checksum.

const compressed = try cz.zlib.compress(data, allocator, .{});
  • Zlib header (2 bytes) + deflate + Adler-32 checksum
  • Dictionary compression supported
  • Common in PNG images, PDF files

Use Deflate when: You need raw deflate without wrappers.

const compressed = try cz.zlib.compressDeflate(data, allocator, .{});
const decompressed = try cz.zlib.decompressDeflate(compressed, allocator, .{});
  • Raw deflate stream, no headers
  • Dictionary compression supported
  • Used inside ZIP files, HTTP chunked encoding

Need compression?
|
+- Need maximum speed?
| +- Control both ends? -> LZ4 Block (36 GB/s)
| +- Need self-describing? -> Snappy (31 GB/s)
|
+- Need best ratio?
| +- One-time compress? -> Brotli best
| +- Repeated compress? -> Zstd best
|
+- Need HTTP compatibility?
| +- Modern browsers only? -> Brotli
| +- Universal support? -> Gzip
|
+- Need streaming?
| +- Fast + checksums? -> LZ4 Frame
| +- Best ratio? -> Zstd
|
+- Not sure?
+- Zstd default (best overall balance)
  1. Default choice: Zstd — excellent at everything
  2. Speed critical: LZ4 Block — 36+ GB/s
  3. Web content: Brotli (static) or Gzip (dynamic)
  4. Real-time: Snappy — fast with self-describing format
  5. File archives: LZ4 Frame — checksums + streaming

See Benchmarks for detailed performance data.