How to enable Gzip and Brotli compression in Nginx - Rocketeers app

  [ Rocketeers ](/)   

[Login](https://rocketeersapp.com/login) 

 On this page

 Knowledge
---------

How to enable Gzip and Brotli compression in Nginx
==================================================

### [\#Performance](https://rocketeersapp.com/knowledge/performance)

Learn how to enable Gzip compression in Nginx (and add Brotli) to shrink text assets and speed up page loads, with real config and verification commands.

 Published by [Mark van Eijk](https://rocketeersapp.com/author/mark-van-eijk) on June 23, 2026 · 4 minute read

1. [Enable Gzip in Nginx](#content-enable-gzip-in-nginx)
2. [Reload Nginx](#content-reload-nginx)
3. [Verify it works](#content-verify-it-works)
4. [Add Brotli for a better ratio](#content-add-brotli-for-a-better-ratio)
5. [Which should you choose](#content-which-should-you-choose)
6. [Conclusion](#content-conclusion)

Compression is one of the cheapest performance wins you can ship. Text assets like HTML, CSS, JavaScript, and JSON compress extremely well, often by 70-80%, so enabling it cuts transfer size and improves load time for every visitor. The good news: to enable Gzip compression in Nginx you only need a handful of directives. This guide covers Nginx Gzip, then adds Brotli for an even better ratio.

[\#](#content-enable-gzip-in-nginx "Permalink")Enable Gzip in Nginx
-------------------------------------------------------------------

Gzip is built into Nginx, so enabling it is just configuration. Add this to the `http {}` block in `/etc/nginx/nginx.conf` (or a file included from it):

 ```
http {
    gzip on;
    gzip_comp_level 5;
    gzip_min_length 256;
    gzip_vary on;
    gzip_proxied any;
    gzip_types
        text/plain
        text/css
        text/xml
        application/json
        application/javascript
        application/xml+rss
        application/atom+xml
        image/svg+xml;
}

```

What each directive does:

- **`gzip on`** — turns compression on. By default Nginx only compresses `text/html`, which is why `gzip_types` matters.
- **`gzip_types`** — the MIME types to compress. List your text-based assets here. There's no point compressing already-compressed formats like JPEG, PNG, or WOFF2, so leave those out.
- **`gzip_comp_level`** — compression effort from 1 to 9. Higher means smaller files but more CPU per request. Levels 4-6 are the sweet spot; past that you burn CPU for marginal size gains. Start at 5.
- **`gzip_min_length 256`** — skip tiny responses. Compressing a 50-byte payload can make it larger and wastes CPU, so only compress responses of at least 256 bytes.
- **`gzip_vary on`** — adds `Vary: Accept-Encoding` so caches and CDNs store compressed and uncompressed variants separately.
- **`gzip_proxied any`** — compress responses even when the request comes through a proxy. Useful behind a load balancer or CDN.

[\#](#content-reload-nginx "Permalink")Reload Nginx
---------------------------------------------------

Always test the config before reloading so a typo doesn't take the server down:

 ```
nginx -t && systemctl reload nginx

```

`nginx -t` validates the syntax; the reload only runs if the test passes. A reload is graceful, so existing connections aren't dropped.

[\#](#content-verify-it-works "Permalink")Verify it works
---------------------------------------------------------

Don't assume it's working, check the response headers. Request a text asset and ask for Gzip:

 ```
curl -H 'Accept-Encoding: gzip' -I https://example.com

```

Look for this in the output:

 ```
content-encoding: gzip
vary: Accept-Encoding

```

If `Content-Encoding: gzip` is present, compression is active. If it's missing, the most common causes are the response type not being in `gzip_types`, the body being under `gzip_min_length`, or a proxy in front stripping the `Accept-Encoding` header. Note that browsers send `Accept-Encoding` automatically; the `-H` flag just forces it for the test.

[\#](#content-add-brotli-for-a-better-ratio "Permalink")Add Brotli for a better ratio
-------------------------------------------------------------------------------------

Brotli typically compresses 15-25% smaller than Gzip on text, and every modern browser supports it. The catch: **Brotli is not bundled with Nginx by default.** You need the `ngx_brotli` module, either compiled in or loaded as a dynamic module.

On Debian/Ubuntu the dynamic modules are often available as a package:

 ```
apt install libnginx-mod-brotli

```

Then load the modules at the very top of `nginx.conf` (before the `http {}` block):

 ```
load_module modules/ngx_http_brotli_filter_module.so;
load_module modules/ngx_http_brotli_static_module.so;

```

Now configure Brotli inside `http {}`, alongside Gzip. Keeping both means clients that don't support Brotli still fall back to Gzip:

 ```
http {
    brotli on;
    brotli_comp_level 5;
    brotli_types
        text/plain
        text/css
        application/json
        application/javascript
        image/svg+xml;

    # static precompression
    brotli_static on;
    gzip_static on;
}

```

`brotli_static on` and `gzip_static on` enable **static precompression**: if a `style.css.br` or `style.css.gz` file sits next to `style.css`, Nginx serves the precompressed version directly instead of compressing on the fly. This is ideal for build artifacts, you compress once at deploy time at maximum level and pay zero CPU per request. Generate the files in your build step and ship them alongside the originals.

Test and reload exactly as before:

 ```
nginx -t && systemctl reload nginx

```

To verify Brotli, ask for it explicitly and check for `content-encoding: br`:

 ```
curl -H 'Accept-Encoding: br' -I https://example.com

```

[\#](#content-which-should-you-choose "Permalink")Which should you choose
-------------------------------------------------------------------------

You don't have to choose, run both. Configure Brotli and Gzip together and let the browser negotiate: capable clients get Brotli, everything else falls back to Gzip. For a deeper comparison of ratios and CPU cost, see [Brotli vs Gzip](/brotli-vs-gzip).

[\#](#content-conclusion "Permalink")Conclusion
-----------------------------------------------

Enabling Gzip in Nginx is a few directives and a reload, and it pays off on every text response you serve. Add `gzip on` with a sensible `gzip_types` list and `gzip_comp_level 5`, confirm it with `curl`, then layer Brotli on top via `ngx_brotli` for a better ratio with Gzip as the fallback. For build assets, precompress with `brotli_static`/`gzip_static` to get maximum compression at no runtime cost.

Compression is one piece of the puzzle. To go further, see how it fits into [optimizing website performance](/optimize-website-performance) and how serving precompressed assets helps your [time to first byte](/ttfb).

### Subscribe to our newsletter

Do you want to receive regular updates with fresh and exclusive content to learn more about web development, hosting, security and performance? Subscribe now!

  Fill in your email address to receive updates  Subscribe 

#### More in [\#Performance](https://rocketeersapp.com/knowledge/performance)

- [How to optimize server performance](https://rocketeersapp.com/knowledge/optimize-server-performance)
- [How to optimize website performance](https://rocketeersapp.com/knowledge/optimize-website-performance)
- [How to measure TTFB (Time To First Byte)](https://rocketeersapp.com/knowledge/ttfb)
- [How to enable and configure OPcache for faster PHP](https://rocketeersapp.com/knowledge/enable-opcache-php)
- [A complete guide to caching in Laravel](https://rocketeersapp.com/knowledge/laravel-cache)
- [How database indexing works (with MySQL examples)](https://rocketeersapp.com/knowledge/database-indexing)

 [View all 13 articles →](https://rocketeersapp.com/knowledge/performance)
