ZSTD vs LZ4 vs ZLIB Compression in MasterDnsVPN: Performance Trade‑offs Explained

MasterDnsVPN supports three compression algorithms—ZSTD for high compression ratios, LZ4 for minimal latency, and ZLIB for broad compatibility—selectable per-session via internal/compression/types.go with built-in safety guards against decompression bombs.

MasterDnsVPN implements a pluggable compression layer in internal/compression/types.go that supports TypeZSTD, TypeLZ4, and TypeZLIB (deflate) for tunneling DNS traffic. Choosing the right algorithm requires balancing CPU usage, memory footprint, and bandwidth savings, especially when handling thousands of small packets per second. The design uses sync.Pool across all three implementations to minimize allocation churn in high-throughput scenarios.

How Compression Works in MasterDnsVPN

The compression logic resides entirely in internal/compression/types.go, exposing four compression types: TypeZSTD, TypeLZ4, TypeZLIB, and TypeOff. The core API consists of CompressPayload() and TryDecompressPayload(), both of which enforce a hard 10 MiB decompression limit via maxDecompressedSize to prevent denial-of-service attacks. When compressing, the caller supplies a compType and a minSize threshold (default 100 B); if the payload is smaller than minSize or compression fails to reduce size, the data is sent uncompressed with TypeOff.

Detailed Comparison of Compression Algorithms

ZSTD (Highest Compression Ratio)

ZSTD achieves the best compression ratios, often 30–40% size reduction on typical DNS-tunnel traffic, by building dictionaries and using entropy coding. However, this comes at moderate CPU cost. The implementation pools zstd.Encoder and zstd.Decoder objects using sync.Pool to amortize allocation costs. Compression is invoked via encoder.EncodeAll(data, nil), while decompression resets the pooled decoder with decoder.Reset(bytes.NewReader(data)) and streams into a bounded buffer. This makes ZSTD ideal for bandwidth-constrained mobile or satellite links where CPU is less constrained than network capacity.

LZ4 (Maximum Speed)

LZ4 prioritizes throughput over ratio, delivering ~400–500 MiB/s per core with only 10–20% size reduction. The implementation prepends a 4-byte little-endian original-size header (compatible with Python’s lz4.block API) before calling lz4.CompressBlock. Decompression extracts this header, validates it against maxDecompressedSize, and calls lz4.UncompressBlock into a pre-allocated slice. Memory usage is minimal, requiring only a single scratch buffer per operation, making LZ4 optimal for low-latency LAN-to-LAN tunnels.

ZLIB (Balanced Fallback)

ZLIB (deflate) offers a middle ground between ZSTD and LZ4. It uses the standard library’s flate package with compression level 1 for a balance of speed and ratio. The code maintains pools of flate.Writer and flate.Reader objects wrapped around reusable bytes.Buffer instances. While slower than LZ4, ZLIB provides broad compatibility with existing infrastructure that expects RFC 1950/1951 streams, serving as a reliable fallback for environments with built-in deflate support.

Safety Mechanisms and Memory Management

All three algorithms share identical safety guards defined in internal/compression/types.go. Decompression is aborted if the output would exceed maxDecompressedSize (set to 10 MiB), returning ErrDecompressedTooLarge. Each compressor uses sync.Pool to recycle heavy objects—ZSTD and ZLIB pool complex stateful encoders/decoders, while LZ4 pools only lightweight scratch buffers. This design is crucial for packet-driven VPNs that may process thousands of payloads per second without triggering garbage collection pauses.

Practical Configuration and Code Examples

Compressing a Payload Before Transmission

import "github.com/masterking32/MasterDnsVPN/internal/compression"

// Compress with ZSTD if payload exceeds 200 bytes
compressed, usedType := compression.CompressPayload(
    payload, 
    compression.TypeZSTD, 
    200,
)
// usedType indicates whether compression was applied (TypeZSTD) or skipped (TypeOff)

Decompressing Received Data

// Decompress based on header-indicated type received from client
decompressed, ok := compression.TryDecompressPayload(data, compType)
if !ok {
    // Handle ErrDecompressedTooLarge or corruption
}

Summary

  • ZSTD provides the highest compression ratios (30–40%) at moderate CPU cost, ideal for bandwidth-constrained mobile or satellite links.
  • LZ4 delivers the fastest throughput (~500 MiB/s) with minimal memory footprint, best for low-latency LAN tunnels.
  • ZLIB offers portable, medium-ratio compression suitable for environments requiring standard deflate streams.
  • All algorithms enforce a 10 MiB decompression limit in TryDecompressPayload and use sync.Pool in internal/compression/types.go to minimize allocations.

Frequently Asked Questions

Which compression type is the default in MasterDnsVPN?

The default selection depends on your runtime configuration. The codebase is optimized for speed-first deployments using LZ4 unless explicitly configured for ZSTD or ZLIB via the compType parameter passed to CompressPayload.

Can I disable compression entirely?

Yes. Passing TypeOff as the compType disables compression. Additionally, the library automatically returns uncompressed data when the payload is smaller than minSize (default 100 B) or when the compression algorithm fails to reduce the total size.

How does MasterDnsVPN prevent decompression bomb attacks?

All three algorithms validate the decompressed size against maxDecompressedSize (10 MiB) before allocation. If the limit is exceeded, TryDecompressPayload returns ErrDecompressedTooLarge and aborts the operation, preventing memory exhaustion attacks.

Is there a performance difference between the pooling implementations?

While all three use sync.Pool, ZSTD and ZLIB maintain pools of complex encoder/decoder objects that persist dictionaries and state, whereas LZ4 only pools lightweight scratch buffers. This makes LZ4 slightly more efficient in terms of garbage collection pressure during sustained high-throughput scenarios.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →