Enabling Gzip on Nginx servers (including Laravel Forge)

Posted on March 23, 2015 | By Matt Stauffer

Warning: This post is over a year old. I don't always update old posts with new information, so some of this information may be out of date.

I recently got an email from Google saying Karani has a few pages that are loading too slowly on mobile, and therefore will be penalized in its search results. I was shocked, because heavy mobile optimization has been a priority on Karani since day one.

I went to Google PageSpeed results they linked to, and found that Gzip wasn't enabled (learn more about Gzip). So, here are the steps I took to turn it back on:

1. Figure out your settings

I chose to copy the settings recommended by HTML5Boilerplate--that's what I had been using on my former Apache server and they worked great. H5bp is a wonderfully-curated collection of wisdom that I'm happy to benefit from.

You can find them here: h5bp nginx config

2. SSH into your server, and edit your nginx configuration

SSH into your server. Have your sudo password ready.

I'll use vim, but you can use whatever editor you prefer.

sudo vim /etc/nginx/nginx.conf

You can see that there's already a block of settings regarding Gzip; you could always just modify those and un-comment out the right lines. But since we're already prepared with our HTML5Boilerplate version, why don't we just wipe these lines:

        # Gzip 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_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;

3. Add your configuration settings

Where the old Gzip settings were, paste your new settings. These are what they are at the time of writing this article:

  # 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    256;

  # 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.
  # text/html is always compressed by HttpGzipModule

4. Restart Nginx

You can use the Forge nginx restart dropdown, but since you're SSH'ed in you can also just run sudo service nginx restart.

5. Test

Type any URL into CheckGzipCompression.com. You can test both html pages (e.g. https://karaniapp.com/) or individual assets like your JavaScript and CSS.

CheckGzipCompression.com seems to be inconsistent. Directions coming soon on how to do it yourself, and Chris Fidao suggests https://redbot.org.

5. Profit

That's it--you're now Gzip-compressing all of your basic text-based assets and few other freebies image types as well. Go forth and wow Google.

Comments? I'm @stauffermatt on Twitter

Tags: forge  •  laravel  •  optimization  •  gzip