nginx gzip_static: why are the non-compressed files required?

tompave asked:

I’m working with nginx 1.4.4 running on Ubuntu 12.04.4.
nginx is reverse-proxing a cluster of Rails application servers.

Static files (mostly assets) are served directly, without hitting the application servers.
I’ve set it up to gzip responses and to use pre-compressed files when available.

http {
  gzip on;
  gzip_http_version 1.0;
  gzip_proxied any;
  # other ngx_http_gzip_module directives...

  server {
    # proxy configuration

    location ^~ /assets/ {
      gzip_static on;
      expires max;
      add_header Cache-Control public;
      # root is inherited
      try_files $uri =404;
      error_page 404 /404.html;

This works.
I’ve tested it using a real pre-gzipped asset and a dummy non-compressed asset with the same name but different content:

/assets/application-a45d6...e2593.css         # dummy content
/assets/application-a45d6...e2593.css.gz      # real CSS

I could see that toggling gzip_static on and off would cause nginx to correctly serve the expected version of the file.
So far, so good.

However, this setup only works if the non-compressed version of the file is also present. Having only the pre-compressed version will cause a 404.

The documentation says:

With the “always” value (1.3.6), gzipped file is used in all cases, without checking if the client supports it. It is useful if there are no uncompressed files on the disk anyway or the ngx_http_gunzip_module is used.

(yes: I’ve tried both on and always, and I’ve also tried to add gunzip on. Nothing changed)

It seems to suggest that having only the compressed versions of the files is ok. Is this really the case? Is there anything wrong in my configuration?

My answer:

It’s possible that you’ve found a bug. But in general you want both files anyway, for three reasons:

  1. A few clients won’t request compressed data, and if you force it on them with gzip_static always; they might not understand it.
  2. To ensure that the file is always found, and the request isn’t passed upstream to Rails or being caught by the 404 handler (the possible bug). One of which is probably what’s happening.
  3. Having nginx compress or uncompress the file at runtime means it must do so repeatedly, eating up valuable CPU that could be used to run your application. It’s much less CPU intensive to simply send a static resource.

View the full question and any other answers on Server Fault.

Creative Commons License
This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.