Use Brotli where you can, with Gzip as a fallback. Brotli typically produces smaller files than Gzip for HTML, CSS and JavaScript, and every current major browser supports it over HTTPS. Gzip is supported everywhere and is the safety net for older clients. Enable both on your server or CDN, and the browser picks the best one it supports.
Below you will find what compression does, how Gzip, Brotli and the newer Zstandard compare, copy-paste configuration for Nginx, Apache and Cloudflare, and how to confirm it is working.
Key takeaways
- Use Brotli where you can with Gzip as a fallback, because Brotli typically produces smaller files for HTML, CSS and JavaScript.
- Check compression by looking for a content-encoding header of br, gzip or zstd on your HTML, CSS and JavaScript files.
- Do not compress images such as JPEG, PNG, WebP or AVIF, as they are already compressed, though SVG compresses well.
- Use Brotli levels 4 to 6 or Gzip 5 or 6 for dynamic pages, and save the highest levels for static assets compressed at build time.
What does text compression do?
When a browser requests a page it sends an Accept-Encoding header listing the compression formats it understands, for example gzip, deflate, br, zstd. If the server supports one of them, it compresses the response and labels it with a Content-Encoding header. The browser decompresses it before use.
Text files are highly repetitive, so they shrink dramatically. HTML, CSS, JavaScript, JSON, XML and SVG often compress to a fraction of their original size. Images such as JPEG, PNG, WebP and AVIF, WOFF2 fonts, video and PDFs are already compressed, so compressing them again wastes server CPU for little or no gain.
Gzip vs Brotli vs Zstandard: which is best?
| Gzip | Brotli | Zstandard (zstd) | |
|---|---|---|---|
| Browser support | Universal | All current major browsers | Chrome and Edge 123+, Firefox 126+; Safari partial |
| Compression ratio | Good | Better, especially at high levels | Similar to Brotli at comparable speeds |
| Needs HTTPS | No | In practice, yes (browsers only request it over HTTPS) | Same as Brotli in practice |
| Server support | Built into Nginx, Apache, IIS, every CDN | Apache 2.4.26+ (mod_brotli), Nginx via a third-party module, most CDNs |
Growing; some CDNs, fewer servers |
When Google introduced Brotli in 2015, it reported compression ratios 20 to 26% higher than Zopfli, a highly optimised Gzip-compatible compressor. In everyday use the gain over typical Gzip settings varies by file, but Brotli is consistently smaller.
Our recommendation for most small-business sites: Brotli first, Gzip as fallback. Treat zstd as a bonus your CDN may already provide, not something to configure by hand yet.
How do I check if compression is enabled?
- Open your site in Chrome, press F12 and go to the Network tab.
- Reload, click the main HTML document and look under Response Headers for
content-encoding. You should seebr,gziporzstd. - Repeat for a CSS and a JavaScript file.
From a terminal:
curl -sI -H "Accept-Encoding: br, gzip" https://www.example.com/ | grep -i content-encoding
If nothing comes back, compression is off for that response. Lighthouse checks compression of the HTML document in its Document request latency insight, which you will see in a MakeItFlow website speed test. Check CSS and JavaScript files by hand, as that insight only covers the page itself.
How do I enable Gzip and Brotli in Nginx?
Gzip is built in, but most types are off by default: Nginx only compresses text/html unless you list others, and the default compression level is 1. Add this to the http block:
gzip on;
gzip_vary on;
gzip_comp_level 5;
gzip_min_length 256;
gzip_proxied any;
gzip_types text/plain text/css text/xml application/javascript
application/json application/xml image/svg+xml
application/rss+xml font/ttf font/otf;
Brotli needs the ngx_brotli module, which is not part of core Nginx. Many Linux distributions and third-party repositories package it as a dynamic module. Once installed:
load_module modules/ngx_http_brotli_filter_module.so;
load_module modules/ngx_http_brotli_static_module.so;
http {
brotli on;
brotli_comp_level 5;
brotli_static on;
brotli_types text/plain text/css text/xml application/javascript
application/json application/xml image/svg+xml
application/rss+xml font/ttf font/otf;
}
load_module lines go at the top of nginx.conf, outside the http block. brotli_static on serves pre-compressed .br files if your build process creates them. Test with nginx -t before reloading.
How do I enable Gzip and Brotli in Apache?
Apache uses mod_deflate for Gzip and mod_brotli (Apache 2.4.26 and later) for Brotli. In your virtual host or .htaccess:
<IfModule mod_brotli.c>
AddOutputFilterByType BROTLI_COMPRESS text/html text/plain text/xml text/css \
text/javascript application/javascript application/json image/svg+xml
BrotliCompressionQuality 5
</IfModule>
<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css \
text/javascript application/javascript application/json image/svg+xml
</IfModule>
Clients that accept Brotli get Brotli; others fall back to Gzip. Apache's documentation describes Brotli quality 5 as a reasonable balance for dynamic content. Both modules must be enabled (on Debian and Ubuntu, a2enmod brotli deflate). On shared hosting you may only be able to use .htaccess, and Brotli may not be installed; ask your host.
How do I enable compression on Cloudflare or another CDN?
If your site sits behind Cloudflare, compression to visitors is handled for you. Cloudflare compresses responses to visitors by default, choosing Zstandard, Brotli or Gzip according to your plan's default settings and what each visitor's browser supports. You can adjust this with Compression Rules. Cloudflare requests content from your origin with accept-encoding: br, gzip, so it is still worth enabling compression on your server.
Other CDNs and many managed WordPress hosts also compress automatically. Check the response headers rather than assuming.
What compression level should I use?
Higher levels give smaller files but use more CPU per request:
- Dynamic responses (HTML generated per request): Brotli 4 to 6, Gzip 5 or 6.
- Static assets compressed once at build time: Brotli 11 and Gzip 9 are fine, because the cost is paid once.
Very high levels on dynamic content can increase server response time and cancel out the benefit.
Is compression a security risk?
Apache's own documentation warns that some web applications are vulnerable to information disclosure when compressed data is sent over TLS, known as the BREACH family of attacks. The risk applies to pages that reflect user input alongside secrets such as CSRF tokens. Most frameworks mitigate this with per-request token masking. It is not a reason to turn compression off for static CSS and JavaScript.
Frequently asked questions
Can I use Gzip and Brotli at the same time?
Yes, and you should. The server reads the browser's Accept-Encoding header and picks one format per response. Make sure Vary: Accept-Encoding is sent so caches store the versions separately.
Why are some files still uncompressed after I enabled it?
Check the file types: a MIME type missing from your gzip_types, brotli_types or AddOutputFilterByType list will be skipped, and Nginx compresses only HTML unless you list other types. Files from third-party domains follow those servers' settings, which you cannot change, though you can self-host or remove the script.
Should I compress images with Gzip?
No. JPEG, PNG, WebP, AVIF and GIF are already compressed, so Gzip or Brotli adds CPU cost for almost no saving. SVG is the exception: it is text and compresses well.
Does compression help Core Web Vitals?
Indirectly. Smaller HTML, CSS and JavaScript download faster, which helps First Contentful Paint and Largest Contentful Paint, especially on mobile connections. See our guide to improving LCP for where it fits.
My host is shared and won't enable Brotli. What can I do?
Make sure Gzip is on, which almost every host supports. Putting a CDN in front of the site is the easiest way to get Brotli or zstd without server access. Our guide on whether you need a CDN explains the options.
What to do next
Check the content-encoding header on your HTML, CSS and JavaScript today. If any are uncompressed, apply the snippet for your server or switch it on at your CDN, then re-test. For a full picture of what else is slowing delivery, see our guide to reducing TTFB or run a free website audit with MakeItFlow.
Sources
Written by the MakeItFlow team
We build the website audit these guides are based on. Every fact is checked against the primary sources listed above and this guide was last reviewed on 25 October 2026 . How we research and check
Check your own site in 30 seconds
Run a free audit covering speed, SEO, DNS, email authentication and security headers — and get a prioritised fix list.