Brotli and Zstandard Compression: Advanced HTTP Compression for Better Page Speed

Brotli and Zstandard Compression: Advanced HTTP Compression for Better Page Speed

HTTP compression is one of the highest-ROI performance optimizations available — implemented correctly, it reduces response sizes by 60-90% with almost no CPU overhead. Most websites are already using gzip, but gzip is the baseline, not the ceiling. Brotli has been widely supported since 2016 and delivers 15-25% better compression than gzip at equivalent speeds. Zstandard (Zstd), developed by Facebook and standardized in 2021, offers even better ratios with significantly faster decompression. In 2026, running only gzip is leaving measurable page speed and SEO performance on the table.

Why HTTP Compression Matters for SEO

The connection between HTTP compression and SEO runs through Core Web Vitals, specifically Time to First Byte (TTFB) and Largest Contentful Paint (LCP). Large, uncompressed HTML and JavaScript responses slow down initial rendering. The browser can’t start parsing HTML it hasn’t received, and it can’t execute JavaScript it hasn’t downloaded. Compression directly reduces the bytes transferred, which directly reduces load time, which directly improves Core Web Vitals scores that feed into Google’s Page Experience ranking signals.

Beyond rankings, compression affects user experience metrics that correlate with business outcomes. A 500ms reduction in page load time corresponds to measurable improvements in bounce rate, conversion rate, and time on site across virtually every industry benchmark study available. Compression is one of the few optimizations that benefits users on every device and connection type — a smartphone user on 4G benefits even more from Brotli than a desktop user on fiber.

For large sites with many pages — e-commerce catalogs, content publishers, enterprise documentation — compression also reduces CDN and server bandwidth costs. For high-traffic sites processing millions of requests daily, the cost savings can be significant.

Gzip: The Baseline You’re Probably Already Running

Gzip has been the default HTTP compression standard since the late 1990s. It’s based on the DEFLATE algorithm (LZ77 + Huffman coding), and it remains widely supported by 100% of modern browsers and virtually all web servers.

Gzip Compression Levels

Gzip offers compression levels 1-9, where 1 is fastest with lowest compression ratio and 9 is slowest with highest compression ratio. For dynamic content, levels 4-6 are the standard sweet spot. For static assets served from a CDN, pre-compressing at level 9 is appropriate because the compression cost is paid once at deploy time, not on every request.

In nginx, gzip configuration looks like:

gzip on;
gzip_comp_level 6;
gzip_min_length 1000;
gzip_types text/html text/css application/javascript application/json image/svg+xml;
gzip_vary on;

The gzip_vary on directive is critical — it adds the Vary: Accept-Encoding response header, which tells CDNs and proxy caches to serve the correct compressed version based on what the client supports.

What Gzip Doesn’t Compress Well

Gzip is ineffective on already-compressed formats: JPEG, PNG, GIF, MP4, MP3, ZIP, PDF. Attempting to gzip these files actually increases their size slightly due to compression headers. Configure your server to exclude these MIME types from gzip.

Brotli: The Modern Standard You Should Be Using

Brotli was developed by Google and open-sourced in 2015. It’s designed specifically for HTTP content compression and uses a different algorithm than gzip — LZ77 plus Huffman coding plus context modeling, with a built-in static dictionary of common web content patterns. This static dictionary is why Brotli outperforms gzip on HTML, CSS, and JavaScript: these file types contain patterns that Brotli’s dictionary was specifically trained on.

Brotli vs. Gzip: Real Performance Comparison

The performance difference depends on content type and compression quality setting. Benchmark data from Google’s original Brotli paper and subsequent independent testing shows:

  • HTML files: Brotli quality 6 delivers 15-21% smaller files than gzip level 6 at similar compression speed.
  • CSS files: 17-25% smaller with Brotli at equivalent quality settings.
  • JavaScript: 15-20% smaller, with the largest gains on unminified JS.
  • Font files (WOFF/WOFF2): Modest gains; WOFF2 already uses a compression algorithm similar to Brotli internally.

For a 200KB JavaScript bundle, a 20% compression improvement means 40KB less data transferred on every page load. At 100,000 page loads per day, that’s 4GB of bandwidth saved daily — and a measurable reduction in load time for users on constrained connections.

Implementing Brotli on nginx

Brotli support in nginx requires the ngx_brotli module, which is not included in the standard nginx distribution. On Debian/Ubuntu:

apt-get install nginx-module-brotli

Or compile nginx with the module. Configuration:

brotli on;
brotli_comp_level 6;
brotli_min_length 1000;
brotli_types text/html text/css application/javascript application/json image/svg+xml;
brotli_static on;

The brotli_static on directive enables serving pre-compressed .br files when they exist, eliminating on-the-fly compression CPU cost for static assets.

Brotli Quality Levels

Brotli quality levels run from 0-11. Quality 11 produces the best compression ratio but is significantly slower than gzip — inappropriate for dynamic content. For on-the-fly dynamic content, quality 4-6 matches gzip speed while delivering better compression ratios. For pre-compressed static assets, quality 11 is appropriate since compression happens at deploy time.

This is the key operational decision: compress dynamic content at quality 4-6 in real time, pre-compress static assets at quality 11 and serve from CDN. This gives you the best of both worlds: responsiveness for dynamic content, maximum compression for static assets.

Browser Support and Graceful Fallback

Brotli is supported by all modern browsers (Chrome, Firefox, Safari, Edge) with market share representing 95%+ of web traffic in 2026. Browsers that support Brotli advertise it via the Accept-Encoding: br, gzip, deflate header. Your server should check this header and serve Brotli to supporting clients, gzip to others. nginx’s brotli module handles this automatically.

Struggling with page speed and Core Web Vitals? Our technical SEO team implements advanced compression, CDN configuration, and full performance optimization stacks. Apply to work with us →

Zstandard (Zstd): The Next Generation

Zstandard, developed by Yann Collet at Facebook (Meta) and released as an open standard (RFC 8878) in 2021, represents a different design philosophy from both gzip and Brotli. Where Brotli optimized specifically for web content, Zstandard optimizes for general-purpose high-performance compression with exceptional decompression speed.

Zstd’s Key Advantages

Zstd’s headline achievement is its decompression speed: it can decompress at 1-3 GB/s on a single CPU core, roughly 5-10x faster than gzip and 3-5x faster than Brotli. For web performance, faster decompression means the browser can start parsing the decompressed content sooner — reducing the processing latency that follows network transfer.

Compression ratio comparison at equivalent levels: Zstd level 3 matches gzip level 9 quality while being 3-5x faster to compress. For dynamic content (where you’re compressing on every request), Zstd level 3 delivers gzip-level-9 quality at gzip-level-1 speed. This is a transformative tradeoff for high-throughput web servers.

Zstd Dictionary Training

One of Zstd’s most powerful features for web use cases is dictionary-based compression. Similar to Brotli’s built-in static dictionary, Zstd allows you to train a custom dictionary on a sample of your actual content, then use that dictionary for both compression and decompression. For a website where most pages share a similar HTML structure, CSS class names, and JavaScript patterns, a custom dictionary can improve compression ratios by an additional 20-40% compared to dictionary-less compression.

To train a dictionary:

zstd --train /path/to/sample-files/* -o domain-content.dict
zstd --dict domain-content.dict input.html -o input.html.zst

The dictionary must be distributed to clients (browsers) for decompression. This is handled via the upcoming HTTP dictionary transport mechanism (an IETF draft being actively developed as of 2026).

Current HTTP/Browser Support for Zstd

As of 2026, Zstd HTTP compression support is growing but not yet universal. Chrome 122+ supports zstd in Accept-Encoding. Firefox support is in development. Safari does not yet support Zstd in HTTP compression. This means Zstd should be implemented as an enhancement for Chrome users with gzip/Brotli fallback for all others — not as a replacement for Brotli.

Nginx Zstd support requires the ngx_http_zstd_filter_module, which is not yet in mainline nginx distributions. Apache support is available via mod_zstd. Cloudflare supports Zstd compression transparently at the edge for clients that advertise support.

CDN-Level Compression: Delegating to the Edge

For most production websites, the most practical path to Brotli and Zstd support is through CDN configuration rather than origin server changes. Cloudflare, CloudFront, Fastly, and Akamai all support Brotli compression at the edge, applying it transparently without any origin server changes.

Cloudflare Brotli Configuration

Cloudflare automatically compresses cached responses with Brotli for supporting browsers. For dynamic (non-cached) content, Brotli is applied in real time at the edge. This requires zero configuration changes on your origin server — Cloudflare handles the Accept-Encoding negotiation and serves the appropriate encoding to each client.

To verify Cloudflare Brotli is active, inspect response headers with curl:

curl -H "Accept-Encoding: br" -I https://yourdomain.com | grep content-encoding

If you see content-encoding: br, Brotli is working. If you see content-encoding: gzip, verify your Cloudflare compression settings in the Speed → Optimization section.

CloudFront Brotli

AWS CloudFront enables Brotli via Compress Objects Automatically setting in your distribution’s cache behavior. Ensure your cache policy includes Accept-Encoding as a cache key header — this allows CloudFront to cache and serve both Brotli and gzip versions of the same response.

Pre-Compression Workflow for Static Assets

For static assets (CSS bundles, JS bundles, font files, SVGs), the highest-performance approach is pre-compression at build time. This means generating .gz, .br, and optionally .zst variants of every static file during your CI/CD pipeline and deploying them alongside the original files.

Build Pipeline Integration

In a webpack or Vite build:

# Install compression plugins
npm install --save-dev compression-webpack-plugin vite-plugin-compression

# webpack.config.js
const CompressionPlugin = require('compression-webpack-plugin');
const zlib = require('zlib');

plugins: [
  new CompressionPlugin({
    algorithm: 'brotliCompress',
    test: /\.(js|css|html|svg)$/,
    compressionOptions: { params: { [zlib.constants.BROTLI_PARAM_QUALITY]: 11 } },
    filename: '[path][base].br',
  }),
  new CompressionPlugin({
    algorithm: 'gzip',
    test: /\.(js|css|html|svg)$/,
    compressionOptions: { level: 9 },
    filename: '[path][base].gz',
  }),
]

Pre-compressed files are then uploaded to your CDN/static host. When nginx is configured with brotli_static on and gzip_static on, it automatically serves the pre-compressed version, eliminating all runtime compression CPU overhead.

Measuring Compression Performance Impact

Implement compression changes, then measure their actual impact on performance metrics.

Response Size Comparison

Use curl to compare response sizes across encodings:

# Uncompressed
curl -so /dev/null -w "%{size_download}" https://yourdomain.com/app.js

# Gzip
curl -H "Accept-Encoding: gzip" -so /dev/null -w "%{size_download}" https://yourdomain.com/app.js

# Brotli
curl -H "Accept-Encoding: br" -so /dev/null -w "%{size_download}" https://yourdomain.com/app.js

Core Web Vitals Before/After

Run Lighthouse tests before and after implementing Brotli. The metrics most likely to improve are TTFB (if you’re compressing HTML dynamically) and LCP (if your LCP resource is text-based). For JavaScript-heavy SPAs, Time to Interactive often improves significantly with Brotli due to faster JS bundle transfer.

For production measurement, use Google Search Console Core Web Vitals data 28 days post-implementation to see field data improvements. Lab improvements (Lighthouse) should be immediately visible; field improvements accumulate over 4 weeks as CrUX data refreshes.

Frequently Asked Questions

Should I use Brotli or Zstd for my website in 2026?

Use Brotli as your primary compression algorithm — it has universal browser support and delivers significantly better compression than gzip. Add Zstd as an enhancement for Chrome users if your server configuration supports it. In 2-3 years, when Zstd browser support is universal, the recommendation will likely flip. For now, Brotli is the pragmatic standard with Zstd as a progressive enhancement.

Does enabling Brotli increase server CPU usage significantly?

For dynamic content compressed in real time, Brotli at quality 4-6 has CPU overhead comparable to gzip level 6. At quality 11 (maximum), Brotli is significantly slower than gzip and inappropriate for dynamic content. The practical solution for high-traffic sites is to pre-compress static assets at quality 11 and use quality 4-6 for dynamic content — this gives you maximum compression ratios without CPU-scaling problems.

How do I verify that Brotli compression is actually working?

Inspect response headers in Chrome DevTools (Network tab → select a resource → Headers → Response Headers → look for content-encoding: br). Alternatively, use curl with the -H "Accept-Encoding: br" header and check the response headers. If you see content-encoding: gzip despite requesting Brotli, your server either doesn’t support Brotli or isn’t configured to serve it.

Can I use both Brotli pre-compressed files and on-the-fly gzip for the same asset?

Yes, and this is the recommended configuration. Deploy both .br and .gz pre-compressed files alongside the original. Configure nginx with both brotli_static on and gzip_static on. The server will serve the Brotli version to supporting clients, gzip to others, and the uncompressed original only if neither encoding is supported (essentially no modern browser).

Does HTTP compression affect image or video file sizes?

No — JPEG, PNG, GIF, WebP, AVIF, MP4, and other binary media formats are already internally compressed. HTTP compression of these formats either produces no size reduction or actually slightly increases file size due to compression headers. Always exclude binary media MIME types from your compression directives. The performance impact of HTTP compression is almost entirely from text-based resources: HTML, CSS, JavaScript, JSON, XML, and SVG.

How do Brotli and gzip interact with HTTP/2 and HTTP/3?

Compression and HTTP version are independent transport optimizations. Brotli works over HTTP/1.1, HTTP/2, and HTTP/3 (QUIC). HTTP/2 and HTTP/3 provide additional performance benefits through multiplexing (multiple requests over a single connection) and header compression (HPACK/QPACK), but these don’t substitute for response body compression. The two optimizations stack: HTTP/2 + Brotli outperforms either one alone. Enabling both is strongly recommended for any production website targeting modern performance standards.