Enable gzip on Nginx by setting gzip on in the http or server block and adding CSS, JavaScript and JSON to gzip_types. The filter defaults to off, so only text/html is compressed until that list grows. Run nginx -t, reload, and look for Content-Encoding: gzip.
What gzip compression does on Nginx
Gzip on Nginx is the ngx_http_gzip_module filter. It compresses the response during the request, so the browser downloads fewer bytes of HTML and other text.
Nginx skips a response that already has a Content-Encoding header. If an application upstream already gzipped the body, Nginx does not compress it a second time.
You need permission to edit the Nginx config and reload the process. On Linux hosting at WebJi the account is shared cPanel and LiteSpeed, so nginx.conf is not yours to edit. Make this change on a Linux VPS, where you control the web server, then confirm the result with curl.
Nginx directives that turn gzip on
Put this block in the http context, or in one server block if only that site should compress. Leave text/html out of gzip_types. Nginx compresses that type whenever gzip is on, and listing it again produces a duplicate MIME type warning.
gzip on;
gzip_vary on;
gzip_comp_level 5;
gzip_min_length 1000;
gzip_proxied expired no-cache no-store private auth;
gzip_types text/plain text/css text/javascript application/javascript application/json application/xml image/svg+xml;
- gzip on turns the filter on. The built-in default is off.
- gzip_vary on sends Vary: Accept-Encoding, so a cache does not store one body for every client.
- gzip_comp_level takes 1 to 9. The default is 1. Level 5 sits in the middle of that range.
- gzip_min_length 1000 skips bodies under 1000 bytes. The default is 20, and the size is read only from Content-Length.
- gzip_proxied lists which proxied responses to compress. Without it, the default off skips any request that carries a Via header.
- gzip_types adds MIME types beyond HTML. CSS and JavaScript stay uncompressed until you name them.

Where the gzip block goes in Nginx
Open the main file, usually /etc/nginx/nginx.conf, and find any gzip line already inside the http block. Replace that line so you do not keep two copies.
The same directives are valid in http, server and location. A server block overrides http for that site. Put gzip off in one server if that site must stay uncompressed.
On Debian and Ubuntu, site files are included from /etc/nginx/sites-enabled/. On RHEL-style systems they are often in /etc/nginx/conf.d/. The last included file wins if it sets gzip again.
A shared cPanel account has no nginx.conf for you. An .htaccess file does not switch this filter on. Use the .htaccess guide only when the host documents Apache or LiteSpeed rules for that account.
Gzip level, minimum length and proxied responses
Level 1 is the default and uses the least CPU. Level 9 is the maximum and spends more CPU on every response. Level 5 is the middle setting in the block above. Move toward 1 if the CPU is already busy.
gzip_min_length looks only at Content-Length. A chunked response with no Content-Length has no length Nginx can compare, so that response can skip compression.
The module default of 20 bytes will compress tiny replies, where the gzip wrapper can outweigh the saving. The block on this page uses 1000 bytes, the floor in the Nginx admin-guide sample.
| gzip_proxied value | What Nginx compresses |
|---|---|
| off | Nothing that arrived with a Via header. This is the default. |
| expired no-cache no-store private auth | Proxied responses a shared cache should not keep. This is the set in the block above. |
| any | Every proxied request. Use any when a CDN sends Via and you still want public pages compressed. |
Swap the proxied line to any if curl against the public URL shows no Content-Encoding while the same URL on the origin, without the CDN, does.
How to test that Nginx gzip is working
Request gzip and read the headers. Content-Encoding: gzip on a 200 response means that URL was compressed.
curl -sI -H "Accept-Encoding: gzip" https://example.com/
- Content-Encoding: gzip is the result you want.
- Vary: Accept-Encoding should appear when gzip_vary is on.
- A small file with no Content-Encoding can be under gzip_min_length.
- A browser tab can show the old cached file. curl does not.
Run the same command on a CSS or JavaScript URL. HTML can pass while those files fail, because gzip_types still lists only text/html.
If you log $gzip_ratio, Nginx records the original size divided by the compressed size for that response. It is a log variable, not a header the browser sends.
When Nginx should use gzip_static
gzip_static on does not compress during the request. For a URL /css/app.css, Nginx looks for /css/app.css.gz and sends that file when the client accepts gzip. If the .gz file is missing, it sends the plain file.
The directive lives in a separate module and is missing from some open-source builds. Create the .gz files yourself before you rely on it. Keep the gzip directive for HTML and JSON that are built per request.
Clients that cannot accept gzip, while you store only compressed files, need the gunzip module instead. It is also separate, and gzip on does not turn it on.
Gzip and Brotli on the same Nginx server
Gzip is the encoding browsers and proxies already accept, and the module ships with Nginx. Brotli needs ngx_brotli, which stock Nginx does not include. After you add that module, brotli on and brotli_types follow the same idea as the gzip list.
With both enabled, Nginx chooses from the client Accept-Encoding header. A browser that offers br can receive Brotli. Other clients still get gzip. Turn gzip on and pass the curl test before you add Brotli.
Do not gzip JPEG, PNG, WebP, GIF, WOFF2, MP4 or zip. Those formats are already compressed. A second pass spends CPU and can make the file larger. Zstd is another optional module, not part of this filter.
Reload Nginx after a gzip change
Test the file before a reload. A failed test leaves the running config in place.
- Run sudo nginx -t and wait until it reports that the syntax is ok.
- Run sudo systemctl reload nginx, or sudo nginx -s reload where systemd is not used.
- Repeat the curl header check on the homepage and on one CSS file.
If nginx -t fails, fix the line it names. A missing semicolon stops the reload. So does a MIME type Nginx does not recognize.
The usual misses are a later include that sets gzip off, CSS and JavaScript left out of gzip_types, gzip_proxied still off behind a CDN, or a curl command that did not send Accept-Encoding. An image that stays uncompressed is the correct result.
HTTPS does not turn gzip off. The Nginx docs note that compressed responses over TLS can feed a BREACH issue when a page mixes a secret with data an attacker chose. Public CSS and ordinary HTML are the files this block is for.
Frequently Asked Questions
How do I enable gzip compression in Nginx?
Set gzip on in the http or server block, add CSS and JavaScript types to gzip_types, run nginx -t, and reload. text/html is compressed without being listed. The directive defaults to off.
How do I test whether Nginx gzip is working?
Run curl -sI -H "Accept-Encoding: gzip" on the URL. A compressed response includes Content-Encoding: gzip. Test a CSS or JavaScript file as well, because HTML can pass while those types are still missing.
Which gzip level and minimum length should I use?
Use a level from 1 to 9. The default is 1. Level 5 is a middle setting. Set gzip_min_length above the default of 20 bytes so tiny responses are skipped. This page uses 1000 bytes, read only from Content-Length.
Which file types should Nginx gzip?
Gzip HTML, CSS, JavaScript, JSON, XML, SVG and plain text. Leave out JPEG, PNG, WebP, GIF, WOFF2, MP4 and zip, because those formats are already compressed.
Why is Nginx not compressing my CSS and JavaScript?
gzip_types starts as text/html only, and HTML is compressed even when you do not list it. Add text/css and application/javascript, reload, and request the file with Accept-Encoding: gzip. Also check that a later file did not set gzip off.
What is the difference between gzip and Brotli on Nginx?
Gzip ships with Nginx and is widely understood. Brotli needs the ngx_brotli module, which stock Nginx does not include. When both are enabled, Nginx follows the encodings named in Accept-Encoding.
Can I enable Nginx gzip on shared Linux hosting?
No. Shared cPanel does not give you nginx.conf. On WebJi Linux hosting, LiteSpeed compresses responses on the server. Editing this file needs a VPS where you can reload Nginx.

