MaxCDN Blog

Nginx performance tips using ngx_pagespeed

April 22, 2013

Here at MaxCDN we’ve been working with Google’s Make the Web Faster team to optimize our Content Delivery Network. The simplicity of their goal is great: You know the web? Make it faster. 

We’re always excited to try new technologies, like WebP. However, new developments often come with implementation caveats: we’re eager to work with Google and other partners to field-test, identify issues, and resolve them as they appear. The more we collaborate to battle-harden the technology, the faster we can deliver your content with even better performance.

Today, we’d like to share a few lessons we’ve learned while testing the ngx_pagespeed module developed by the Google’s PageSpeed team.

First up: setup was painless. We spun up a new server, compiled the latest stable Nginx with ngx_pagespeed, and we were done. The Nginx PageSpeed settings were ready to be added to the main virtual host config.

Enabling PageSpeed took a single line (pagespeed on;). But, as with any test deployment, we discovered and resolved a few issues:

  • A quick gotcha: Make sure the cache directory (FileCachePath in the Nginx config) is already created, and writeable by the Nginx daemon.

  • We noticed whitespace wasn’t being trimmed as expected, so we explicitly added the collapse_whitespace filter. Similarly, HTML comments were not always removed, so we directly enabled the remove_comments filter. (Please note: Whitespace is not part of “core” config because in some cases JS depends on whitespace )

  • Certain URLs were being rewritten and included our Varnish HTTP port (8080). The fix was to have PageSpeed rewrite the urls back to the regular domain:
    pagespeed MapRewriteDomain;

  • Nginx was handing content directly to PageSpeed, even if it was compressed. Currently, PageSpeed can’t read zipped content, so we disabled compression in the PHP layer with a FastCGI parameter: fastcgi_param HTTP_ACCEPT_ENCODING "invalid";
    (Note: Content was compressed by Nginx after the PageSpeed step.)

So, did it work? We used a Google Analytics experiment to split traffic and measure results on our homepage. When testing content delivery, we disabled WordPress plugins that could affect our statistics (we wanted to compare a baseline Nginx with the PageSpeed module).

Screen Shot 2013-04-21 at 9.08.17 AM

With PageSpeed enabled, we shaved 1.57 seconds from our average page load (seen above), dropped our bounce rate 1%, and our exit percentage 2.5%. In sum, we squeezed out extra performance with nothing but a few extra lines in our nginx config files.

Sign us up for more. We are continuing to test the module with the PageSpeed team, and our goal is to make it available across our CDN and to all of our customers – stay tuned!

In case you want to run Nginx with PageSpeed, here’s our full config:

server {
  #port to listen on
  listen 80;

  # server name

  # root location
  root /var/www/;

  # access log
  access_log /var/log/nginx/ main;

  # PageSpeed
  pagespeed on;

  # let's speed up PageSpeed by storing it in the super duper fast memcached
  pagespeed MemcachedThreads 1;
  pagespeed MemcachedServers "localhost:11211";

  # show half the users an optimized site, half the regular site
  pagespeed RunExperiment on;
  pagespeed AnalyticsID UA-XXXXXXXXXX-1;
  pagespeed ExperimentVariable 1;
  pagespeed ExperimentSpec "id=1;percent=50;level=CoreFilters;enabled=collapse_whitespace,remove_comments;";
  pagespeed ExperimentSpec "id=2;percent=50";

  # Filter settings
  pagespeed RewriteLevel CoreFilters;
  pagespeed EnableFilters collapse_whitespace,remove_comments;

  # needs to exist and be writable by nginx
  pagespeed FileCachePath /var/ngx_pagespeed_cache;

  # Varnish talks to us as but when we rewrite
  # urls we should use because that's what the
  # outside world uses for us.
  pagespeed MapRewriteDomain;

  # This is a temporary workaround that ensures requests for pagespeed
  # optimized resources go to the pagespeed handler.
  location ~ ".pagespeed.([a-z].)?[a-z]{2}.[^.]{10}.[^.]+" { }
  location ~ "^/ngx_pagespeed_static/" { }
  location ~ "^/ngx_pagespeed_beacon$" { }



A big thank you to the following people who helped make this happen:


    As a maxcdn customer as well, thanks for the example vhost config. Going to try adding ngx_pagespeed to Centmin Mod based Nginx installer :)

  • Ashish

    Hi there

    I am using The following on my blog

    1. MaxCDN

    2. Cloudflare
    Bother of them using W3Total cache plugin
    and now i just added google’s Pagespeed
    And my site went haywire cause the images are not loading javascript and everything else that was supposed to be parsed by my CDN
    Please help !!!

  • Frank

    Hey taylor, thanks for the great article. My name is frank. I was the original idea behind bootstrapcdn but can take 0 credit because other than the first beta site i dropped off the project. So if you see justin in the office tell him i said wazzup! And he might want to look at

    Question. I am trying to get NginX to sit in front of a few IIS Servers and accomplish the following tasks:

    1. Offload SSL requests.
    2. Proxy to IIS Servers (all running identical content) but pass the Ip address and use “sticky sessions” as opposed to round robin.
    3. Use Pagespeed to minfiy / optimize / etc.
    4. Cache everything on the linux nginx server (disk is fine)
    5. ignore urls such as bootstrapcdn or google jquery
    6. Rewrite static domains to a maxCDN bucket.

    The idea is to be able to get a cheap nginx server to sit in front of expensive IIS servers. If you have looked at cloud pricing, windows servers usually eat 2x resources, and cost 2x as much. So 4x!!! putting nginx in front of the IIS servers saves a ton of $$$ and lets you fly with less windows resources. I know having just one nginx server is a single point of failure, but i am guessing you could replicate this among multiple servers and with geo dns or dns failover really make sure that things are always up. And with a CDN taking the bulk of the hits, chances are you will go down if your code is sloppy.

    Any case, any pointers you can give us on the subejct would be SUPERB.
    I have no idea how to configure nginx properly, but understand you guys have a hotline to its original author.

    PS. Posted it on server fault.

  • Alex V

    I set up my pagespeed using memcached like you suggested and it’s working great!

    Just wondering, how do I clear the pagespeed cache when I add new content? I assume it would be just clearing out memcached?

  • Guest

    Thanks very much for the insight!

  • shakalandy

    Thanks very much for the insight!

    Could you please outline your varnish configuration in this case? Thanks!