Back to blog
SRE & Performance September 8, 2026

HTTP Compression in Production: Gzip vs Brotli vs Zstandard Benchmarks for SREs

Automate WhatsApp Alerts
Start Free ➔

HTTP Compression in Production: Gzip vs Brotli vs Zstandard Benchmarks for SREs

Compressing HTTP payload data is an essential optimization for web performance and cloud egress cost reduction. In high-throughput production infrastructure, HTTP compression represents a fundamental systems engineering trade-off: trading origin CPU cycles and worker memory buffers for reduced network bandwidth and shorter packet transit times.

When compression algorithms or quality levels are misconfigured—such as executing dynamic Brotli level 11 compression inside a synchronous request worker—the CPU overhead spikes, worker thread pools saturate, container CFS quotas trigger aggressive throttling, and tail latency ($p99$) explodes.

Site Reliability Engineers must evaluate compression algorithms across the entire operational cost curve: compression ratio, encoding CPU throughput, decoding speed, cache fragmentation risks, and client compatibility.

Client Request (Accept-Encoding: zstd, br, gzip)
   │
   ▼
Edge CDN / Reverse Proxy Cache Lookup
   ├── Cache Hit (Precompressed .br / .zst representation) ──► Serve Immediately (0 CPU Cost)
   └── Cache Miss / Dynamic API Payload
         │
         ▼
Dynamic Compression Engine (Origin Web Worker)
   │
   ├── Check Payload Size (If Size < 1 KB ──► Skip Compression)
   ├── Check Content-Type (If Image / Video / PDF ──► Skip Compression)
   ├── Select Algorithm & Quality Level (Brotli L4 / Gzip L5 / Zstd L3)
   │
   ▼
TLS Record Encryption ──► TCP / QUIC Packet Transmission

1. Deconstructing the Algorithms: Gzip vs. Brotli vs. Zstandard

Understanding the mathematical and architectural foundations of each compression algorithm determines its proper operational placement in production stacks.

1.1 Gzip (DEFLATE / LZ77 + Huffman)

  • Architecture: Combines the LZ77 sliding window algorithm (32 KB window) with dynamic Huffman coding.
  • Production Characteristics: Highly predictable CPU and memory footprints. Universal support across 100% of web browsers, automated API clients, and legacy middleboxes.
  • SRE Trade-Off: Reaches diminishing returns above level 6. Encoding throughput drops significantly at levels 7–9 without meaningful byte savings.

1.2 Brotli (LZ77 + 2nd Order Context Modeling + 120KB Static Dictionary)

  • Architecture: Employs a massive sliding window (up to 16 MB) combined with a built-in static dictionary containing over 13,000 common HTML, CSS, JavaScript, and XML phrases.
  • Production Characteristics: Produces 15% to 25% smaller payloads than Gzip on text-based web assets. Decompression in browsers is fast and memory-efficient.
  • SRE Trade-Off: Asymmetrical CPU cost. Levels 1–4 are fast enough for dynamic API traffic; levels 5–9 require moderate CPU; levels 10–11 are computationally prohibitive for runtime encoding (requiring up to 100x more CPU time) and should strictly be reserved for build-time precompression.

1.3 Zstandard (Zstd / FSE Finite State Entropy + Large Search Window)

  • Architecture: Developed by Meta, Zstd replaces traditional Huffman coding with Finite State Entropy (FSE) based on Asymmetric Numeral Systems (ANS). Supports sliding windows up to 2 GB and custom pre-trained dictionaries.
  • Production Characteristics: Extremely high encoding throughput (3–5x faster than Gzip at equivalent ratios) and lightning-fast decompression speeds (> 1 GB/s per core).
  • SRE Trade-Off: Browser support is expanding in modern Chromium engines (via zstd Content-Encoding in RFC 8878), but legacy clients and some cloud CDN edge nodes require fallback negotiation to Brotli or Gzip. Exceptional for service-to-service microservice RPCs and internal data ingestion pipelines.

2. Production Benchmarks: Compression Ratio vs. CPU Throughput

The following benchmarks measure encoding throughput (MB/s per core) and compression ratio across a representative 50 MB corpus of production web assets (bundled JavaScript, minified CSS, HTML templates, and JSON API payloads) on an AMD EPYC 7763 Linux instance:

Algorithm & LevelCompressed SizeCompression Ratio ($CR$)Bandwidth Savings ($S$)Encode SpeedDecode SpeedRecommended SRE Workload
Uncompressed$50.00\text{ MB}$$1.00\times$$0.0%$N/AN/APayload $< 1\text{ KB}$ or Binary
Gzip Level 1$14.80\text{ MB}$$3.38\times$$70.4%$$95\text{ MB/s}$$290\text{ MB/s}$High-throughput dynamic APIs
Gzip Level 6$12.10\text{ MB}$$4.13\times$$75.8%$$32\text{ MB/s}$$310\text{ MB/s}$Standard compatibility baseline
Gzip Level 9$11.90\text{ MB}$$4.20\times$$76.2%$$11\text{ MB/s}$$310\text{ MB/s}$Avoid (Inefficient CPU cost)
Brotli Level 4$11.40\text{ MB}$$4.39\times$$77.2%$$52\text{ MB/s}$$380\text{ MB/s}$Dynamic HTML / JSON responses
Brotli Level 6$10.60\text{ MB}$$4.72\times$$78.8%$$18\text{ MB/s}$$390\text{ MB/s}$Semi-static cached edge content
Brotli Level 11$9.80\text{ MB}$$5.10\times$$80.4%$$0.8\text{ MB/s}$$410\text{ MB/s}$Precompressed static assets only
Zstandard L3$11.20\text{ MB}$$4.46\times$$77.6%$$240\text{ MB/s}$$1150\text{ MB/s}$Microservices / Internal APIs
Zstandard L9$10.10\text{ MB}$$4.95\times$$79.8%$$45\text{ MB/s}$$1200\text{ MB/s}$High-volume log & telemetry streams

3. The SRE Total Cost of Ownership (TCO) Equation

To evaluate whether higher compression quality is economically beneficial, model the total operational cost function:

$$ \text{Total Cost} = \text{Egress Network Cost} + \text{Compute CPU Cost} + \text{Latency Penalty Cost} $$

Bandwidth Savings Formula

$$ S = 1 - \frac{B_{\text{compressed}}}{B_{\text{original}}} $$

Economic Trade-Off Calculation

For an origin cluster serving $R = 2,000\text{ req/sec}$ with an average dynamic payload of $200\text{ KB}$ and AWS cloud egress priced at $$0.08\text{ per GB}$:

Monthly Uncompressed Egress: 2,000 × 200 KB × 86,400 × 30 = 1,036.8 TB ($82,944 / month)

Option A: Brotli Level 4 (77.2% Savings, 52 MB/s encode speed)
- Compressed Egress: 236.4 TB ($18,912 / month)
- Bandwidth Cost Savings: $64,032 / month
- Additional CPU Cores Required: ~8 vCPUs ($240 / month)
- Net Monthly Benefit: +$63,792 / month (Optimal)

Option B: Dynamic Brotli Level 11 (80.4% Savings, 0.8 MB/s encode speed)
- Compressed Egress: 203.2 TB ($16,256 / month)
- Marginal Bandwidth Savings vs Option A: $2,656 / month
- Additional CPU Cores Required: ~500 vCPUs ($15,000 / month)
- Net Monthly Impact: -$12,344 / month (Severe Financial & Latency Loss!)

Dynamic compression at maximum levels creates a net financial deficit and introduces 200–500 ms of origin processing delay.

Need to model how origin latency spikes affect your service error budget? Use our interactive SLA Calculator to translate latency and availability budgets into concrete downtime allowances.


4. Local CLI Benchmarking Harness

Run this reproducible shell script on your application servers to benchmark Gzip, Brotli, and Zstandard against your specific production API responses:

#!/usr/bin/env bash
# Production SRE Compression Benchmark Suite
set -euo pipefail

INPUT_FILE="${1:-payload.json}"

if [[ ! -f "$INPUT_FILE" ]]; then
  echo "Usage: $0 <path-to-sample-payload.json>"
  exit 1
fi

ORIGINAL_SIZE=$(wc -c < "$INPUT_FILE")
echo "======================================================================"
echo " HTTP COMPRESSION BENCHMARK: $(basename "$INPUT_FILE")"
echo " Original Uncompressed Size: $(numfmt --to=iec-i --suffix=B "$ORIGINAL_SIZE") ($ORIGINAL_SIZE bytes)"
echo "======================================================================"

printf "%-14s %-8s %-12s %-12s %-14s %-10s\n" "Algorithm" "Level" "Output Size" "Ratio" "Savings %" "Encode Time"

# 1. Benchmark Gzip
for lvl in 1 6 9; do
  START=$(date +%s%N)
  gzip -c -"$lvl" "$INPUT_FILE" > /tmp/test_out.gz
  END=$(date +%s%N)
  OUT_SIZE=$(wc -c < /tmp/test_out.gz)
  DUR_MS=$(( (END - START) / 1000000 ))
  RATIO=$(awk "BEGIN {printf \"%.2f\", $ORIGINAL_SIZE / $OUT_SIZE}")
  SAVINGS=$(awk "BEGIN {printf \"%.1f\", (1 - ($OUT_SIZE / $ORIGINAL_SIZE)) * 100}")
  printf "%-14s %-8s %-12s %-12s %-14s %-10s\n" "Gzip" "$lvl" "$(numfmt --to=iec-i --suffix=B "$OUT_SIZE")" "${RATIO}x" "${SAVINGS}%" "${DUR_MS}ms"
done

# 2. Benchmark Brotli
for lvl in 1 4 6 11; do
  START=$(date +%s%N)
  brotli -q "$lvl" -c "$INPUT_FILE" > /tmp/test_out.br
  END=$(date +%s%N)
  OUT_SIZE=$(wc -c < /tmp/test_out.br)
  DUR_MS=$(( (END - START) / 1000000 ))
  RATIO=$(awk "BEGIN {printf \"%.2f\", $ORIGINAL_SIZE / $OUT_SIZE}")
  SAVINGS=$(awk "BEGIN {printf \"%.1f\", (1 - ($OUT_SIZE / $ORIGINAL_SIZE)) * 100}")
  printf "%-14s %-8s %-12s %-12s %-14s %-10s\n" "Brotli" "$lvl" "$(numfmt --to=iec-i --suffix=B "$OUT_SIZE")" "${RATIO}x" "${SAVINGS}%" "${DUR_MS}ms"
done

# 3. Benchmark Zstandard
for lvl in 1 3 9; do
  START=$(date +%s%N)
  zstd -q -"$lvl" -c "$INPUT_FILE" > /tmp/test_out.zst
  END=$(date +%s%N)
  OUT_SIZE=$(wc -c < /tmp/test_out.zst)
  DUR_MS=$(( (END - START) / 1000000 ))
  RATIO=$(awk "BEGIN {printf \"%.2f\", $ORIGINAL_SIZE / $OUT_SIZE}")
  SAVINGS=$(awk "BEGIN {printf \"%.1f\", (1 - ($OUT_SIZE / $ORIGINAL_SIZE)) * 100}")
  printf "%-14s %-8s %-12s %-12s %-14s %-10s\n" "Zstandard" "$lvl" "$(numfmt --to=iec-i --suffix=B "$OUT_SIZE")" "${RATIO}x" "${SAVINGS}%" "${DUR_MS}ms"
done

rm -f /tmp/test_out.gz /tmp/test_out.br /tmp/test_out.zst
echo "======================================================================"

5. Web Server Configuration Best Practices

5.1 Nginx High-Performance Compression Configuration

Configure Nginx to serve precompressed .br and .gz static files while restricting dynamic compression to safe quality levels:

# /etc/nginx/conf.d/compression.conf

# 1. Enable Precompressed Static Asset Delivery (Zero Runtime CPU)
brotli_static on;
gzip_static on;

# 2. Dynamic Brotli Configuration (For Dynamic HTML / API JSON)
brotli on;
brotli_comp_level 4; # Sweet spot: Excellent ratio with low CPU overhead
brotli_min_length 1024; # Skip payloads smaller than 1 KB
brotli_types text/plain text/css application/javascript application/json
             application/xml application/xml+rss image/svg+xml;

# 3. Dynamic Gzip Fallback Configuration (For Legacy Clients)
gzip on;
gzip_comp_level 5;
gzip_min_length 1024;
gzip_proxied any;
gzip_vary on; # Emits 'Vary: Accept-Encoding' to prevent cache poisoning
gzip_types text/plain text/css application/javascript application/json
           application/xml application/xml+rss image/svg+xml;

Testing your live server headers, compression formats, and Vary policies? Use our HTTP Header Checker to verify that Content-Encoding: br and Vary: Accept-Encoding are returned correctly.


6. SRE Guardrails and Failure Prevention

Enforce strict architectural guardrails to prevent compression from becoming a point of failure:

  1. Enforce Minimum Payload Thresholds (min_length 1024): Compressing payloads smaller than 1 KB often results in larger files due to container header overhead, while wasting CPU cycles.
  2. Exclude Pre-Compressed Binary Media: Never enable compression on image/jpeg, image/png, image/webp, image/avif, video/mp4, or .zip files. These formats are already compressed; recompressing them burns CPU with 0% byte reduction.
  3. Always Emit Vary: Accept-Encoding: If reverse proxies or CDNs cache a compressed representation without the Vary header, legacy clients requesting uncompressed data may receive compressed binary streams they cannot decode.
  4. Precompress at Build Time: In CI/CD pipelines, generate .br and .gz files at maximum quality (Brotli Level 11) during asset compilation (Webpack / Vite / Next.js). Edge servers can then stream precompressed files directly from disk via sendfile() without touching CPU.

7. Troubleshooting Runbook: Resolving Compression Regressions

When origin CPU saturates or $p99$ latency spikes following a release, follow this ten-step diagnostic sequence:

  1. Verify client request headers using curl -sS -I -H "Accept-Encoding: br, gzip" https://example.com/api/data.
  2. Inspect Content-Encoding and Content-Length response headers to confirm which algorithm the origin or CDN edge selected.
  3. Audit origin CPU consumption and container throttling using cat /proc/pressure/cpu and Kubernetes container_cpu_cfs_throttled_seconds_total.
  4. Check whether dynamic Brotli is configured above level 5 in production web server configurations.
  5. Inspect reverse-proxy cache hit ratios to ensure static assets are served from cache rather than dynamically compressed on every request.
  6. Verify that the build pipeline generated .br and .gz static sidecars alongside JavaScript and CSS bundles.
  7. Test whether third-party API proxies are double-compressing responses (e.g., Gzip over Brotli), causing client decode errors.
  8. Audit edge CDN compression settings (e.g., Cloudflare Polish or Fastly Brotli) to ensure compression occurs at the edge POP rather than the origin.
  9. Temporarily reduce dynamic compression levels from Brotli L6 to Gzip L4 to provide immediate CPU relief during traffic surges.
  10. Calculate error budget consumption and latency degradation using the Downtime Calculator.

8. SRE Compression Decision Matrix

Workload ClassPreferred FormatTarget Quality LevelExecution LayerGuardrail Policy
Static JS / CSS / HTMLBrotliLevel 11Build CI/CD PipelinePrecompress .br & .gz files
Dynamic JSON APIBrotli / GzipBrotli L4 / Gzip L5Origin Web ServerBypass if payload $< 1\text{ KB}$
Internal MicroservicesZstandardLevel 3Service Mesh / gRPCNegotiate via Accept-Encoding
High-Volume TelemetryZstandardLevel 5Logging Agent (Fluentbit)Stream compression with dictionaries
Images & Media StreamsNoneN/AStorage CDNDisable HTTP compression

9. Engineering Implementation Checklist

  • Configure Build-Time Precompression: Generate static .br (level 11) and .gz (level 9) assets during CI/CD compilation.
  • Enable brotli_static on and gzip_static on: Ensure Nginx/Caddy streams precompressed static assets directly from disk.
  • Cap Dynamic Brotli at Level 4: Prevent origin CPU exhaustion by strictly limiting dynamic runtime compression quality.
  • Set min_length 1024: Disable compression for micro-payloads under 1 KB.
  • Enforce Vary: Accept-Encoding: Prevent CDN cache poisoning between Gzip, Brotli, and uncompressed clients.
  • Exclude Compressed MIME Types: Verify that image, video, and archive MIME types bypass compression filters.
  • Monitor Compression CPU Metrics: Scrape http_compression_cpu_seconds_total and alert on container CPU throttling.
  • Evaluate Zstandard for Internal RPCs: Adopt Zstandard level 3 for internal microservice service-to-service communication.

Related Protocol & Optimization Guides

To maximize network throughput and edge delivery speeds, explore these related resources:

Zero-Code Uptime Alerts

Stop Finding Out About Outages from Angry Users

Get instant WhatsApp & Discord alerts the second your API, website, or server goes down. Setup in 30 seconds with 60-second checks.

WhatsApp & Discord 60-Second Checks Free Forever Plan
Try Pingzo Free

Know before your users do

Connect official WhatsApp notification channels, Discord webhooks, Telegram bots, and public status pages. Start in 30 seconds.

Create Free Monitor