How to speed up WordPress with WP Super Cache & NGINX rules. Use the WP Super Cache Expert modus in combination with Nginx config rules.

Wp Super Cache

WP Super Cache by Donncha O Caoimh, a WordPress developer at Automattic, is a WordPress caching engine that turns dynamic WordPress pages into static HTML files that NGINX can serve very quickly.

Install WP Super Cache and activate it. Turn on caching in easy settings:

Go to the advanced tab and turn on recommended settings.

  1. Compress pages.
  2. Don’t cache pages for known users.
  3. Cache rebuild.
  4. Clear all cache files when a post or page is published or updated.
  5. Extra homepage checks.

Caching should be enabled and your website should be serving cached files by now. The next step is configuring Nginx for WP Super Cache. This step can give you a few milliseconds extra loading time.

Configure NGINX for WP Super Cache

In order to configure Nginx for Wp Super Cache we will have to edit the Nginx Vhost config file. This is one possible configuration we can use. I happen to use Cloudpanel for my test server and will edit the default WordPress 5 Vhost config.

server {
  listen 80;
  listen [::]:80;
  listen 443 ssl http2;
  listen [::]:443 ssl http2;
  {{ssl_certificate_key}}
  {{ssl_certificate}}
  server_name www.domain.com;
  return 301 https://domain.com$request_uri;
}

server {
  listen 80;
  listen [::]:80;
  listen 443 ssl http2;
  listen [::]:443 ssl http2;
  {{ssl_certificate_key}}
  {{ssl_certificate}}
  server_name domain.com www1.domain.com;
  {{root}}

  {{nginx_access_log}}
  {{nginx_error_log}}

  if ($bad_bot = 1) {
    return 403;
  }

  if ($scheme != "https") {
    rewrite ^ https://$host$uri permanent;
  }

  location ~ /.well-known {
    auth_basic off;
    allow all;
  }

  {{basic_auth}}

  #rewrite ^/blog$ /blog/$1 permanent;

  #location /blog/ {
  #  try_files $uri $uri/ /blog/index.php?$args;
  #}

  #include /etc/nginx/pagespeed.conf;
  #pagespeed on;
  #pagespeed FileCachePath "/home/cloudpanel/htdocs/domain.com/wp-content/cache/ngx_pagespeed/";

  try_files $uri $uri/ /index.php?$args;
  index index.php index.html;

  location ~ \.php$ {
    include fastcgi_params;
    fastcgi_intercept_errors on;
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    try_files $uri =404;
    fastcgi_read_timeout 3600;
    fastcgi_send_timeout 3600;
    fastcgi_param HTTPS $fastcgi_https;
    {{php_fpm_listener}}
    {{php_settings}}
  }

set $cache_uri $request_uri;

    # POST requests and URLs with a query string should always go to PHP
    if ($request_method = POST) {
        set $cache_uri 'null cache';
    }  
    if ($query_string != "") {
        set $cache_uri 'null cache';
    }   

    # Don't cache URIs containing the following segments
    if ($request_uri ~* "(/wp-admin/|/xmlrpc.php|/wp-(app|cron|login|register|mail).php
                          |wp-.*.php|/feed/|index.php|wp-comments-popup.php
                          |wp-links-opml.php|wp-locations.php |sitemap(_index)?.xml
                          |[a-z0-9_-]+-sitemap([0-9]+)?.xml)") {

        set $cache_uri 'null cache';
    }  
	
    # Don't use the cache for logged-in users or recent commenters
    if ($http_cookie ~* "comment_author|wordpress_[a-f0-9]+
                         |wp-postpass|wordpress_logged_in") {
        set $cache_uri 'null cache';
    }

    # Use cached or actual file if it exists, otherwise pass request to WordPress
    location / {
        try_files /wp-content/cache/supercache/$http_host/$cache_uri/index.html 
                  $uri $uri/ /index.php;
    }    

    location = /favicon.ico {
        log_not_found off; 
        access_log off;
    }

    location = /robots.txt {
        log_not_found off;
        access_log off;
    }

    location ~ .php$ {
        try_files $uri /index.php;
        include fastcgi_params;
        fastcgi_pass unix:/var/run/php74-fpm.sock;
        #fastcgi_pass 127.0.0.1:9000;
    }

  location ~* ^.+\.(css|js|jpg|jpeg|gif|png|ico|gz|svg|svgz|ttf|otf|woff|eot|mp4|ogg|ogv|webm|webp|zip|swf)$ {
    add_header Access-Control-Allow-Origin "*";
    expires max;
    access_log off;
  }

  if (-f $request_filename) {
    break;
  }
}

I added this code snippet just after the php cgi location block:

set $cache_uri $request_uri;
 
    # POST requests and URLs with a query string should always go to PHP
    if ($request_method = POST) {
        set $cache_uri 'null cache';
    }  
    if ($query_string != "") {
        set $cache_uri 'null cache';
    }   
 
    # Don't cache URIs containing the following segments
    if ($request_uri ~* "(/wp-admin/|/xmlrpc.php|/wp-(app|cron|login|register|mail).php
                          |wp-.*.php|/feed/|index.php|wp-comments-popup.php
                          |wp-links-opml.php|wp-locations.php |sitemap(_index)?.xml
                          |[a-z0-9_-]+-sitemap([0-9]+)?.xml)") {
 
        set $cache_uri 'null cache';
    }  
     
    # Don't use the cache for logged-in users or recent commenters
    if ($http_cookie ~* "comment_author|wordpress_[a-f0-9]+
                         |wp-postpass|wordpress_logged_in") {
        set $cache_uri 'null cache';
    }
 
    # Use cached or actual file if it exists, otherwise pass request to WordPress
    location / {
        try_files /wp-content/cache/supercache/$http_host/$cache_uri/index.html 
                  $uri $uri/ /index.php;
    }    
 
    location = /favicon.ico {
        log_not_found off; 
        access_log off;
    }
 
    location = /robots.txt {
        log_not_found off;
        access_log off;
    }
 
    location ~ .php$ {
        try_files $uri /index.php;
        include fastcgi_params;
        fastcgi_pass unix:/var/run/php74-fpm.sock;
        #fastcgi_pass 127.0.0.1:9000;
    }

After saving the configuration file, you can enable expert mode in the advanced tab of WP Super Cache.

Conclusion

I have tested this configuration on two websites. The first website was loading in 0.8 seconds and with this configuration it loads in 0.7 seconds. The second website was loading in 1.1 seconds and with this configuration it dropped to an amazing 0.6 seconds.

This configuration can speed up WordPress websites between 100 ms and 500 ms. Sometimes it is a 100% performance increase, especially with faster loading websites that now even loads faster. Depending on the website your performance increase can vary from a slightly faster site or a double so fast site.

More interesting resources: