Skip to main content
In this lesson you’ll learn how to enable and verify HTTP compression (gzip) in Nginx. We’ll first measure performance without compression, then enable gzip in the Nginx configuration and confirm responses are compressed and transferred much faster. Note that compressing already-compressed image formats (JPEG, PNG, GIF) usually yields little to no benefit — this demo intentionally inflates JPEG sizes so the difference is easy to observe in browser developer tools. We begin by testing the site with no compression and hitting backend Apache servers. Most text-based assets (HTML, CSS, JS) are already efficient, but artificially large image/jpeg files will exhibit long transfer times when not compressed.
A simple network diagram showing a browser requesting a CSS resource through an NGINX reverse proxy labeled "No Compression" to backend Apache web servers. Arrows indicate NGINX forwards the request to two Apache web servers.
To highlight the effect, we inflate JPEG sizes on the Apache servers, observe the slow transfers in the browser, then enable gzip in Nginx and confirm dramatic improvements.
A simple architecture diagram showing a browser requesting assets (CSS, JS, HTML, JPG, XML) routed through an NGINX reverse proxy with compression. The proxy forwards the requests to multiple Apache web servers.

Preparing the environment

  • Confirm your Nginx reverse proxy forwards requests to Apache upstreams. Example upstream and HTTP-to-HTTPS redirect:
  • Example HTTPS server block on the reverse proxy (shortened for clarity):
Best practice: configure proxy_set_header lines so your backend sees the original Host and client IPs, and include proxy_ssl_server_name on; when proxying to HTTPS backends.

Inflating images for the demo

On the Apache webserver(s) we intentionally inflate the JPEG files to simulate very large images. Run these commands in the images directory:
Example listing prior to inflation:
After fallocate -l 20M, each .jpg reports a much larger size. This produces invalid image contents in many cases — acceptable here because we only demonstrate transfer size and compression behavior, not image fidelity.
Using fallocate as shown will change file contents and can corrupt images. Do this only in test/demo environments where file integrity doesn’t matter.

Monitoring access logs

Tail the Apache access log while exercising the site so you can observe incoming GET requests and response sizes:
Example access log entry:

Testing in the browser (no compression)

  • Open an Incognito/private window, open Developer Tools → Network tab, and load the site.
  • Without compression you’ll see large transferred sizes for the inflated JPEGs and long transfer times (multiple seconds per file).
Example response headers for an uncompressed image (notice Content-Length ~ 20 MB and no Content-Encoding):
A browser screenshot showing a webpage header that reads "This is Phantom, a free, fully responsive site." The developer tools Network panel is open below, listing many GET requests, file names, types and transfer sizes.
Firefox displays both the resource size and the transferred bytes. When uncompressed, they match and transfer times are long for each large image.

Enabling gzip in Nginx

Edit the main Nginx configuration (typically /etc/nginx/nginx.conf) and add gzip settings inside the http block. The key directives to enable and control gzip:
  • gzip on; — enables gzip compression.
  • gzip_vary on; — adds Vary: Accept-Encoding to responses (important for caches).
  • gzip_proxied any; — allow compression when requests come via a proxy.
  • gzip_comp_level 6; — compression level (1–9).
  • gzip_http_version 1.1; — ensures proper handling for HTTP/1.1 clients.
  • gzip_types — list of MIME types to compress (text-based types are priority).
Here is a concise gzip snippet to include under the http block:

What these gzip directives do

Notes:
  • Keep gzip_types focused on compressible, text-based content (HTML/CSS/JS/JSON/XML).
  • Adding image/jpeg to gzip_types generally has little benefit because JPEGs are already compressed; in this demo we included it to illustrate the effect on inflated files.

Validate and reload Nginx

Always test the config before restarting:
If nginx -t reports errors, fix them before reloading.

Verifying compression in the browser

Reload the page in an incognito/private window and watch the Network tab. Compressed responses will include Content-Encoding: gzip and Vary: Accept-Encoding headers. The browser shows a smaller “Transferred” size than the resource “Size” when compression is applied. Example compressed response headers:
You will also see compressed JavaScript/CSS responses with smaller transferred sizes:
A browser window showing the "Phantom" website template with a large headline and placeholder text. The browser's developer tools (Network tab) are open at the bottom, listing many GET requests and resource details.

Consolidated configuration examples

Below is a compact snapshot of common server-wide settings you can place in nginx.conf or your site-specific configuration. Adjust values for your environment.
And a compact server block recap with headers and proxy settings:

HTTP headers reference

For comprehensive information about HTTP headers and their semantics, see:
A screenshot of the MDN Web Docs page titled "HTTP headers," showing explanatory text and section links about different types of HTTP headers. The page layout includes a left navigation column, main article content in the center, and a right-hand table of contents.

Conclusion

  • Enabling gzip in Nginx with a sensible gzip_types list and gzip_vary on; dramatically improves transfer times for compressible content (HTML, CSS, JavaScript, JSON, XML).
  • Most modern image formats (JPEG, PNG, WEBP) are already compressed; gains from gzipping them are usually minimal. This demo inflated JPEGs to make the compression effect visible.
  • Always validate configuration changes with nginx -t before reloading, and verify behavior using multiple clients (Chrome, Firefox, curl) and your browser developer tools.
Additional resources:

Watch Video

Practice Lab