CDN Compression: Brotli vs Gzip Analysis
Why Compression Matters
Text-based assets (HTML, CSS, JavaScript, JSON, SVG) compress dramatically — typically 60-80% size reduction. Compression directly reduces transfer time and bandwidth costs. Every CDN supports compression; the question is which algorithm and how to configure it. For foundational context, read CDN Performance Metrics: What to Measure — FlyFish NWA.
Gzip vs Brotli
| Feature | Gzip | Brotli |
|---|---|---|
| Compression ratio | Baseline | 15-25% better than gzip |
| Compression speed | Fast (all levels) | Fast (levels 1-4), slow (levels 5-11) |
| Decompression speed | Fast | Faster than gzip |
| Browser support | Universal | 97%+ (all modern browsers) |
| HTTPS required | No | Yes (browsers require HTTPS for Brotli) |
Compression Level Trade-offs
Both algorithms offer configurable compression levels:
| Metric | Edge Processing | Origin Processing | Improvement |
|---|---|---|---|
| Latency (p50) | 8–15 ms | 120–300 ms | 15–20x faster |
| Cache Hit Ratio | 85–95% | N/A | Reduces origin load |
| TLS Handshake | 1–5 ms (nearby PoP) | 50–150 ms | 10–30x faster |
| Bandwidth Cost | $0.01–0.04/GB | $0.05–0.12/GB | 3–5x cheaper |
| Availability | 99.99% (multi-PoP) | 99.9% (single DC) | 10x fewer outages |
Gzip levels 1-9:
Level 1: Fast compression, larger files
Level 6: Default balance (most CDNs use this)
Level 9: Maximum compression, slow
Brotli levels 0-11:
Levels 1-4: Fast, for on-the-fly compression at the edge
Level 5-6: Good balance for dynamic content
Level 11: Maximum compression, very slow (pre-compress only)
CDN Compression Strategy
The optimal strategy depends on whether content is static or dynamic:
Static Assets (Pre-Compressed)
Upload both gzip and Brotli-compressed versions at maximum compression level:
# Build step:
brotli -q 11 -o style.css.br style.css # Maximum Brotli
gzip -9 -k style.css # Maximum gzip
# CDN serves the pre-compressed version matching Accept-Encoding
This gives the best compression ratio with zero CDN CPU overhead.
Dynamic Content (On-the-fly)
CDN compresses responses in real-time using lower compression levels:
Accept-Encoding: gzip, br
# CDN selects:
# Brotli level 4 if supported (fast compression, good ratio)
# Gzip level 6 as fallback
Size Comparison
| File Type | Original | Gzip-6 | Brotli-4 | Brotli-11 |
|---|---|---|---|---|
| React bundle (JS) | 500 KB | 145 KB | 130 KB | 118 KB |
| CSS framework | 200 KB | 32 KB | 27 KB | 22 KB |
| HTML page | 50 KB | 14 KB | 12 KB | 10 KB |
| JSON API response | 100 KB | 12 KB | 10 KB | 8 KB |
Brotli-4 (fast, suitable for on-the-fly) beats Gzip-6 by 10-15%. Brotli-11 (pre-compressed) beats Gzip-9 by 15-25%.
CDN Configuration
- Cloudflare — Brotli toggle in dashboard (on by default). On-the-fly compression.
- CloudFront — Supports Brotli when origin sends it. Add Accept-Encoding to cache key.
- Fastly — Automatic gzip. Brotli via origin or Compute@Edge.
- Nginx (origin) —
brotli on; brotli_comp_level 4;with ngx_brotli module.
Compression and Caching
The CDN must cache separate copies for each encoding. The Vary: Accept-Encoding header ensures this. Without it, a Brotli-encoded response might be served to a client that only supports gzip. See HTTP caching fundamentals.