How to Enable Gzip Compression in NGINX on Linux (nginx.conf Guide) Print

  • ngx_http_gzip_module, page-speed, compression, bandwidth, brotli, web-server, core-web-vitals, nginx, vps, linux, javascript, css, gzip, performance, server-administration
  • 2

This guide explains how to enable gzip compression in NGINX on Linux using the built-in ngx_http_gzip_module. Enabling gzip compresses HTTP responses before they are sent to the browser, reducing the transfer size of JavaScript, CSS, HTML, and other text-based assets by 60–80% in most cases. This directly improves page load times, reduces bandwidth consumption, and positively impacts Core Web Vitals scores — with no changes to application code required.

Running NGINX on a VPS or dedicated server? Owned Networks KVM VPS plans give you full root access to configure NGINX however your workload requires. See our KVM VPS plans in Miami and other US and EU locations.

How ngx_http_gzip_module Works

The ngx_http_gzip_module is compiled into NGINX by default on all major Linux distributions — no additional packages are required. When a client sends a request with the Accept-Encoding: gzip header (all modern browsers do), NGINX compresses the response before sending it and sets the Content-Encoding: gzip response header so the browser knows to decompress it. The compression and decompression happen transparently.

Before You Start

  • You must have root or sudo access on the server
  • NGINX must already be installed and running — confirm with sudo systemctl status nginx
  • Always run sudo nginx -t to test configuration before reloading — a syntax error will prevent NGINX from reloading
  • Gzip compression is most effective on text-based assets (HTML, CSS, JS, XML, JSON, SVG). Do not enable it for already-compressed formats such as JPEG, PNG, MP4, ZIP, or PDF — compressing them again adds CPU overhead with no size benefit

Step 1: Create or Edit the NGINX Configuration

The recommended approach is to create a dedicated file in /etc/nginx/conf.d/ rather than editing nginx.conf directly. This keeps your configuration modular and easier to manage.

Option A: Dedicated file (recommended)

sudo nano /etc/nginx/conf.d/gzip.conf

Option B: Edit nginx.conf directly

sudo nano /etc/nginx/nginx.conf

Step 2: Add the Gzip Configuration Block

Add the following inside the http block. If you created a new conf.d file, paste it in directly without wrapping it in an http { } block — NGINX includes conf.d/*.conf files inside the http context automatically.

##
# Gzip Compression Settings
##

gzip on;
gzip_disable "msie6";

gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_buffers 16 8k;
gzip_http_version 1.1;
gzip_min_length 256;
gzip_types
    text/plain
    text/css
    text/xml
    text/javascript
    application/json
    application/javascript
    application/xml
    application/xml+rss
    application/vnd.ms-fontobject
    application/x-font-ttf
    font/woff
    font/woff2
    image/svg+xml;

What Each Directive Does

  • gzip on — enables gzip compression globally for the http context
  • gzip_disable "msie6" — disables gzip for Internet Explorer 6, which had broken gzip support; safe to keep for legacy compatibility
  • gzip_vary on — adds the Vary: Accept-Encoding response header, which tells CDNs and reverse proxies to cache both compressed and uncompressed versions separately
  • gzip_proxied any — enables compression for proxied requests regardless of the request headers; important when NGINX sits behind a load balancer
  • gzip_comp_level 6 — sets the compression level on a scale of 1 (fastest, least compression) to 9 (slowest, most compression). Level 6 is the recommended balance between CPU usage and compression ratio
  • gzip_buffers 16 8k — sets the number and size of buffers used to compress a response. The defaults are suitable for most workloads
  • gzip_http_version 1.1 — only compresses responses for HTTP/1.1 and above. HTTP/1.0 clients do not reliably support gzip
  • gzip_min_length 256 — skips compression for responses smaller than 256 bytes. Compressing tiny files adds overhead without meaningful size reduction
  • gzip_types — the list of MIME types to compress. The text/html type is always compressed when gzip is on and does not need to be listed explicitly

Step 3: Test the Configuration

Before reloading NGINX, test the configuration for syntax errors:

sudo nginx -t

Expected output confirming the configuration is valid:

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

If the test returns an error, fix the issue before proceeding. Do not reload NGINX with a broken configuration.

Step 4: Reload NGINX

Apply the changes with a graceful reload — this applies the new configuration without dropping active connections:

sudo systemctl reload nginx

Or combined with the test as a one-liner:

sudo nginx -t && sudo systemctl reload nginx

Step 5: Verify Gzip is Working

Use curl to send a request with the Accept-Encoding: gzip header and check the response headers. Replace the URL with your own domain and a CSS or JS file path:

curl -I -H 'Accept-Encoding: gzip,deflate' https://your-domain.com/your-file.css

Look for Content-Encoding: gzip in the response headers. A successful response will look similar to this:

HTTP/1.1 200 OK
Server: nginx
Content-Type: text/css; charset=UTF-8
Connection: keep-alive
Vary: Accept-Encoding
Content-Encoding: gzip

If Content-Encoding: gzip does not appear, the file type may not be in your gzip_types list, the file may be smaller than gzip_min_length, or the configuration change was not applied. Recheck with sudo nginx -t and confirm the reload completed successfully.

To also see the compression ratio and actual byte savings, use curl without the -I flag and pipe through wc -c to compare compressed vs uncompressed sizes:

# Compressed size
curl -s -H 'Accept-Encoding: gzip' https://your-domain.com/your-file.css | wc -c

# Uncompressed size
curl -s https://your-domain.com/your-file.css | wc -c

Optional: Brotli Compression

Brotli is a newer compression algorithm developed by Google that typically achieves 20–26% better compression than gzip at equivalent CPU cost. All major modern browsers support it. Brotli requires the ngx_brotli module, which is not bundled with NGINX by default and must be compiled in or installed as a dynamic module. If you are optimizing for maximum performance and your server has a modern NGINX build, brotli is worth evaluating alongside gzip — most configurations run both, serving brotli to clients that support it and gzip as the fallback.

Related Solution

Need a Linux VPS to host your NGINX web server?

Owned Networks KVM VPS plans provide full root access, SSD-backed storage, and support for all major Linux distributions. Deploy an NGINX server in minutes with complete control over your configuration.

  • Deploy in NYC, Miami, Dallas, LA, Seattle, London, or Amsterdam
  • Ubuntu, Debian, AlmaLinux, Rocky Linux, and CentOS available
  • KVM virtualization — full root access, dedicated resources

Compare VPS Locations and Pricing

Frequently Asked Questions

Does enabling gzip affect server CPU usage?

Yes, but minimally for most workloads. Gzip compression adds CPU overhead on the server and decompression overhead on the client, but both are negligible on modern hardware. The bandwidth savings — typically 60–80% for text assets — far outweigh the CPU cost in almost all production scenarios. Setting gzip_comp_level to 6 (the default recommendation) is a well-tested balance. Going above 6 yields diminishing compression returns with meaningfully more CPU usage.

Should I enable gzip for images and video files?

No. JPEG, PNG, GIF, WebP, MP4, and most other binary media formats are already compressed internally. Running gzip on them adds CPU overhead and can actually increase the response size slightly. Only add MIME types to gzip_types that are text-based or uncompressed by nature — HTML, CSS, JavaScript, JSON, XML, SVG, and web fonts.

What is gzip_vary and why does it matter?

gzip_vary on adds the Vary: Accept-Encoding header to compressed responses. This tells CDNs, reverse proxies, and shared caches that the response varies based on whether the client accepts gzip. Without it, a CDN might cache the compressed version and serve it to a client that does not support gzip, resulting in garbled content. Always enable gzip_vary when using gzip behind a CDN or proxy.

What is the difference between gzip and deflate in NGINX?

In the context of HTTP, "gzip" and "deflate" are both listed in the Accept-Encoding header that browsers send, but NGINX's ngx_http_gzip_module only implements gzip. The deflate encoding in HTTP is rarely used in practice and has known interoperability issues. NGINX does not natively implement deflate compression — configuring gzip is the correct approach for NGINX compression.

Why use a separate conf.d file instead of editing nginx.conf?

Editing nginx.conf directly works but makes the configuration harder to manage as it grows. Placing gzip settings in /etc/nginx/conf.d/gzip.conf keeps the main configuration file clean, makes it easy to disable or modify the gzip block independently, and follows the convention used by most NGINX packages where conf.d/*.conf files are automatically included.

Can I enable gzip only for certain locations or virtual hosts?

Yes. Gzip directives can be placed inside server or location blocks instead of the global http block. A setting in a child block overrides the parent. For example, you can enable gzip globally in http but disable it for a specific location that serves binary downloads by adding gzip off; inside that location block.


Was this answer helpful?

KVM VPS & Dedicated Servers

Deploy a Linux VPS in under 2 minutes — AlmaLinux, Rocky Linux, Ubuntu, Debian. Full root access, KVM virtualization, US and EU locations.

« Back