Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is the gzip minimum length directive not being respected?

If I understand correctly it's better not to gzip small resources as they might actually get bigger while still having a performance hit on the CPU. So using the gzip_min_length directive is an obvious solution to that. However, when trying this on a server that runs a REST API I'm working on this doesn't seem to work. When I receive an empty json response, or a very small one, the Content-Encoding header is still present and reading "gzip".

HTTP Response headers

My question is why this setting is not being respected by NginX and what can I do to fix it?

The API is built on the Lumen microframework.

I have attached the Gzip setting I'm using in my nginx.conf:

  # Compression

  # Enable Gzip compressed.
  gzip on;

  # Enable compression both for HTTP/1.0 and HTTP/1.1.
  gzip_http_version  1.1;

  # Compression level (1-9).
  # 5 is a perfect compromise between size and cpu usage, offering about
  # 75% reduction for most ascii files (almost identical to level 9).
  gzip_comp_level    5;

  # Don't compress anything that's already small and unlikely to shrink much
  # if at all (the default is 20 bytes, which is bad as that usually leads to
  # larger files after gzipping).
  gzip_min_length    1000;

  # Compress data even for clients that are connecting to us via proxies,
  # identified by the "Via" header (required for CloudFront).
  gzip_proxied       any;

  # Tell proxies to cache both the gzipped and regular version of a resource
  # whenever the client's Accept-Encoding capabilities header varies;
  # Avoids the issue where a non-gzip capable client (which is extremely rare
  # today) would display gibberish if their proxy gave them the gzipped version.
  gzip_vary          on;

  # Compress all output labeled with one of the following MIME-types.
  gzip_types
    application/atom+xml
    application/javascript
    application/json
    application/rss+xml
    application/vnd.ms-fontobject
    application/x-font-ttf
    application/x-web-app-manifest+json
    application/xhtml+xml
    application/xml
    font/opentype
    image/svg+xml
    image/x-icon
    text/css
    text/plain
    text/x-component;
  # text/html is always compressed by HttpGzipModule
like image 280
Jonathan Avatar asked Oct 21 '15 21:10

Jonathan


People also ask

When should you not use gzip?

If you take a file that is 1300 bytes and compress it to 800 bytes, it's still transmitted in that same 1500 byte packet regardless, so you've gained nothing. That being the case, you should restrict the gzip compression to files with a size greater than a single packet, 1400 bytes (1.4KB) is a safe value.

Why is gzip not working?

The other reason Gzip might not be working is that you have extremely large files on your site. Older version of Gzip have a file size limit of something like 2GB. Any file larger than that will not be compressed using the Gzip algorithm. That is, however, relying on the older algorithms.

Does NGINX support gzip?

You can configure Nginx to use gzip to compress the files it serves on the fly. Those files are then decompressed by the browsers that support it upon retrieval with no loss whatsoever, but with the benefit of a smaller amount of data to transfer between the web server and browser.

Is Brotli better than gzip?

The data is clear that Brotli offers a better compression ratio than GZIP. That is, it compresses your website “more” than GZIP. However, remember that it's not just about the compression ratio, it's also about how long it takes to compress and decompress data.


1 Answers

Confirming my note above, this does seem to correspond to the note in the NGINX gzip module documentation stating "The length is determined only from the “Content-Length” response header field."

With gzip_min_length 1000;, my JSON responses were being gzip'ed, even if they were only 100 bytes.

I changed my application to add the Content-Length: 100 header and NGINX sends the JSON response without using the gzip encoding.

If I change the configuration to gzip_min_length 80; with the same 100-byte Content-Length, then NGINX applies the gzip encoding as expected.

Short story: you need to apply the Content-Length header for NGINX to properly handle the gzip_min_length check.

like image 113
Chad Barth Avatar answered Oct 14 '22 05:10

Chad Barth