Set Up Nginx FastCGI Cache to Reduce WordPress Server Response Time

This tutorial will be showing you how to set up Nginx FastCGI cache to reduce server response time for your WordPress site.

What is Nginx FastCGI Cache?

If you followed my previous tutorials about installing LEMP stack on various Linux distributions, then Nginx is configured to pass PHP request to PHP-FPM because Nginx itself is unable to process PHP code. Let me explain how a LEMP stack website works.

  1. Web browsers send HTTP requests  to Nginx, which tries to fetch the page from file system.
  2. If Nginx found PHP codes in the page, it passes the request to PHP-FPM to process the PHP codes.
  3. If necessary, PHP-FPM will query MySQL/MariaDB database to get what it needs.
  4. PHP-FPM generates a static HTML page, which is then given back to Nginx.
  5. Finally, Nginx sends the static HTML page to web browser.

Nginx is super fast when it comes to serving static HTML pages. However, PHP is known to be slow, although the latest version PHP8 is much faster than previous versions. And MySQL/MariaDB database is another performance bottleneck of LEMP stack websites.

Instead of passing the dynamic page request to PHP-FPM and let it generate HTML page every time, Nginx can cache the generated HTML page so next time it can send cached pages to web browsers, eliminating PHP and database requests.

  • This can greatly improve server response time and reduce load on PHP-FPM and database server.
  • It also allows Nginx to serve web pages from cache when the upstream PHP-FPM or database server is down (MySQL/MariaDB is usually the first process to be killed when your Linux server runs out of memory).

FastCGI is the protocol between Nginx and PHP-FPM so the cache is called FastCGI cache.

How to Configure Nginx FastCGI Cache

Step 1: Edit the Nginx Main Configuration File

Edit Nginx main configuration file.

sudo nano /etc/nginx/nginx.conf

In the http {…} context, add the following 2 lines:

fastcgi_cache_path /usr/share/nginx/fastcgi_cache levels=1:2 keys_zone=phpcache:100m max_size=10g inactive=60m use_temp_path=off;
fastcgi_cache_key "$scheme$request_method$host$request_uri";

nginx fastcgi cache path

The first directive fastcgi_cache_path creates a FastCGI cache. This directive is only available under the http context of an Nginx configuration file.

  • The first argument specifies the cache location in the file system (/usr/share/nginx/fastcgi_cache/).
  • The levels parameter sets up a two-level directory hierarchy under /usr/share/nginx/fastcig_cache/. Having a large number of files in a single directory can slow down file access, so I recommend a two-level directory for most deployments. If the levels parameter is not included, Nginx puts all files in the same directory. The first directory uses one character in its name. The sub-directory uses two characters in its name.
  • The 3rd argument specifies the name of the shared memory zone name (phpcache) and its size (100M). This memory zone is for storing cache keys and metadata such as usage times. Having a copy of the keys in memory enables Nginx to quickly determine if a request is a HIT or MISS without having to go to disk, greatly speed up the check. A 1MB zone can store data for about 8,000 keys, so the 100MB zone can store data for about 800,000 keys.
  • max_size sets the upper limit of the size of the cache (10GB in this example). If not specified, the cache can use all remaining disk space. Once cache reaches its maximum size, Nginx cache manager will remove the least recently used files from the cache.
  • Data which has not been accessed during the inactive time period (60 minutes) will be purged from the cache by the cache manager, regardless of whether or not it has expired. The default value is 10 minutes. You can also use values like 12h (12 hours) and 7d (7 days).
  • Nginx first writes files that are destined for the cache to a temporary storage area (/var/lib/nginx/fastcgi/). use_temp_path=off tells Nginx to write them directly to the final cache directory to avoid unnecessary copying of data between file systems.

The 2nd directive fastcgi_cache_key defines the key for cache lookup. Nginx will apply a MD5sum hash function on the cache key and uses the hash result as the name of cache files. After entering the two directives in the http context, save and close the file.

Step 2: Edit Nginx Server Block

Then open your server block configuration file.

sudo nano /etc/nginx/conf.d/your-domain.conf

Scroll down to the location ~ \.php$ section. Add the following lines in this section.

fastcgi_cache phpcache;
fastcgi_cache_valid 200 301 302 60m;
fastcgi_cache_use_stale error timeout updating invalid_header http_500 http_503;
fastcgi_cache_min_uses 1;
fastcgi_cache_lock on;
add_header X-FastCGI-Cache $upstream_cache_status;

Set Up Nginx FastCGI Cache

  • The fastcgi_cache directive enables caching, using the memory zone previously created by fastcgi_cache_path directive.
  • The fastcgi_cache_valid sets the cache time depending on the HTTP status code. In the example above, responses with status code 200, 301, 302 will be cached for 60 minutes. You can also use time period like 12h (12 hours) and 7d (7 days).
  • Nginx can deliver stale content from its cache when it can’t get updated content from the upstream PHP-FPM server. For example, when MySQL/MariaDB database server is down. Rather than relay the error to clients, Nginx can deliver the stale version of the file from its cache. To enable this functionality, we added the fastcgi_cache_use_stale directory.
  • fastcgi_cache_min_uses sets the number of times an item must be requested by clients before Nginx caches it. Default value is 1.
  • With fastcgi_cache_lock enabled, if multiple clients request a file that is not current in the cache, only the first of those requests is allowed through to the upstream PHP-FPM server. The remaining requests wait for that request to be satisified and then pull the file form the cache. Without fastcgi_cache_lock enabled, all requests go straight to the upstream PHP-FPM server.
  • The 3rd line adds the X-FastCGI-Cache header in HTTP response. It can be used to validate whether the request has been served from the FastCGI cache or not.

Now save and close the server block configuration file. Then test your Nginx configuration.

sudo nginx -t

If the test is successful, reload Nginx.

sudo service nginx reload

or

sudo systemctl reload nginx

The cache manager now starts and the cache directory (/usr/share/nginx/fastcgi_cache) will be created automatically.

Testing Nginx FastCGI Cache

Reload your site’s home page a few times. Then use curl to fetch the HTTP response header.

curl -I http://www.your-domain.com

Like this:

nginx fastcgi cache test

Take a look at the X-FastCGI-Cache header. HIT indicates the response was served from cache.

If you always get the MISS cache status, then you might need to add the following line in Nginx configuration file.

fastcgi_ignore_headers Cache-Control Expires Set-Cookie;

Like this:

fastcgi_cache phpcache;
fastcgi_cache_valid 200 301 302 60m;
fastcgi_cache_use_stale error timeout updating invalid_header http_500 http_503;
fastcgi_cache_min_uses 1;
fastcgi_cache_lock on;
fastcgi_ignore_headers Cache-Control Expires Set-Cookie;
add_header X-FastCGI-Cache $upstream_cache_status;

Some folks might have enabled HTTPS on Nginx, but added above code in the plaint HTTP server block (listen 80;) instead of in the HTTPS server block (listen 443 ssl;). FastCGI cache won’t work if your don’t add the code in the HTTPS server block.

Stuff that Should not be Cached

Login session, user cookie, POST request, query string, WordPress back-end, site map, feeds and comment author should not be cached. To disable caching for the above items, edit your server block configuration file. Paste the following code into the server context, above the location ~ \.php$ line.

set $skip_cache 0;

# POST requests and urls with a query string should always go to PHP
if ($request_method = POST) {
    set $skip_cache 1;
}
if ($query_string != "") {
    set $skip_cache 1;
}

# Don't cache uris containing the following segments
if ($request_uri ~* "/wp-admin/|/xmlrpc.php|wp-.*.php|^/feed/*|/tag/.*/feed/*|index.php|/.*sitemap.*\.(xml|xsl)") {
    set $skip_cache 1;
}

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

Sometimes I want to test the upstream (PHP-FPM and MariaDB) response time, so I also add the following lines to tell Nginx to bypass the FastCGI cache for my own IP addresses.

if ($remote_addr ~* "12.34.56.78|12.34.56.79") {
     set $skip_cache 1;
}

The tilde symbol (~) tells Nginx that what follows is a regular expression (regex). The star symbol * makes the regex case-insensitve. The vertical bar | is for alternation of several values. If the value of $remote_addr variable matches any IP address in the regex, then set the value of $skip_cache to 1.

You can also skip the cache for a local network like below, which will add 10.10.10.0/24 network to the skip list.

if ($remote_addr ~* "12.34.56.78|12.34.56.79|10.10.10..*") { 
    set $skip_cache 1; 
}

Note that if you are using the Google XML sitemap plugin in your WordPress site, then you can probably see the following rewrite rules in your Nginx configuration.

rewrite ^/sitemap(-+([a-zA-Z0-9_-]+))?\.xml$ "/index.php?xml_sitemap=params=$2" last;
rewrite ^/sitemap(-+([a-zA-Z0-9_-]+))?\.xml\.gz$ "/index.php?xml_sitemap=params=$2;zip=true" last;
rewrite ^/sitemap(-+([a-zA-Z0-9_-]+))?\.html$ "/index.php?xml_sitemap=params=$2;html=true" last;
rewrite ^/sitemap(-+([a-zA-Z0-9_-]+))?\.html.gz$ "/index.php?xml_sitemap=params=$2;html=true;zip=true" last;

These rewrite rules should be put below the skip cache rules. If the rewrite rules are above the skip cache rules, then your sitemap will always be cached.  Similarly, if you use the Yoast SEO plugin to generate sitemap, then you also need to move the Yoast rewrite rules below the skip cache rules.

Now in the location ~ \.php$ section, paste the following directives.

fastcgi_cache_bypass $skip_cache;
fastcgi_no_cache $skip_cache;

If the value of $skip_cache is 1, then the first directive tells Nginx to send request to upstream PHP-FPM server, instead of trying to find files in the cache. The second directive tells Nginx not to cache the response. Save the file and reload Nginx.

sudo systemctl reload nginx

or

sudo service nginx reload

How to Automatically Purge Cache with WordPress

First, you need to install and activate the Nginx Helper plugin on your WordPress site. Then go to WordPress Settings -> Nginx helper and tick on the Enable Purge box. The default purging conditions are fine for most WordPress blogs. You can also enable logging to check if purging is working correctly.

nginx fastcgi cache purge wordpress

Click the Save all changes button.

Then you need to install the http-cache-purge module on your Linux server. Run the following command to install it on Ubuntu 18.04 and above. During the installation process, a configuration file will be put under /etc/nginx/modules-enabled/ directory to enable this module.

sudo apt install libnginx-mod-http-cache-purge

You can also install the nginx-extras package to enable this module, but this package also enables many other modules. To keep my Nginx as lightweight as possible, I don’t install the nginx-extras package.

Next, open your Nginx server block configuration file. Add the following lines in the server {...} context.

location ~ /purge(/.*) {
      fastcgi_cache_purge phpcache "$scheme$request_method$host$1";
}

Save and close the file. Then test Nginx configurations.

sudo nginx -t

If the test is successful, reload Nginx.

sudo systemctl reload nginx

Now you can modify one of your posts in WordPress to see if the cache will be automatically purged.

Nginx Cache Sniper Plugin

If the Nginx helper plugin doesn’t work, you can also use the Nginx Cache Sniper plugin on your WordPress site. Install the plugin, then go to WordPress Dashboard -> Tools -> Nginx Cache Sniper to configure it.

nginx cache sniper wordpress

How to Preload Cache

You can generate page cache before visitors come to your website. Nginx FastCGI cache doesn’t provide a way to preload cache. However, you can use the wget tool on another box to download the entire website, which will force Nginx to produce a cache for every web page.

wget -m -p -E -k https://www.yourdomain.com/

Make sure the IP address of the other box isn’t on the bypass list. Wget will create a www.yourdomain.com directory and store the content there.

Sometimes I have to purge the Nginx FastCGI cache and let it regenerate, but I don’t want to manually type the wget command every time. So I create a Cronjob to automate this task.

crontab -e

Put the following line at the end of the crontab file. /tmp/ramdisk/ is a RAM disk I created to store the files, so the content will be written to RAM and my SSD won’t wear out quickly.

@hourly rm /tmp/ramdisk/www.yourdomain.com/ -rf ; wget -m -p -E -k -P /tmp/ramdisk/ https://www.yourdomain.com/

Save and close the file. (I know this isn’t a very nice way to solve the problem, but it gets the job done.)

How to Configure FastCGI Cache for Multiple WordPress Sites

If you installed multiple instances of WordPress site on the same server, then you can create a separate FastCGI cache for each WordPress site.

sudo nano /etc/nginx/nginx.conf

Like this:

fastcgi_cache_path /usr/share/nginx/domain1_fastcgi_cache levels=1:2 keys_zone=domain1:100m max_size=10g inactive=60m use_temp_path=off;
fastcgi_cache_path /usr/share/nginx/domain2_fastcgi_cache levels=1:2 keys_zone=domain2:100m max_size=10g inactive=60m use_temp_path=off;
fastcgi_cache_key "$scheme$request_method$host$request_uri";

Each WordPress site uses a unique key zone. In the above code, there are two key zones domain1 and domain2. Now the Nginx virtual host file for domain1 should use

  location ~ \.php$ {
    fastcgi_pass unix:/run/php/php8.1-fpm.sock;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    include fastcgi_params;
    include snippets/fastcgi-php.conf;

    fastcgi_cache domain1;
    fastcgi_cache_bypass $skip_cache;
    fastcgi_no_cache $skip_cache;
    fastcgi_cache_valid 200 301 302 60m;
    fastcgi_cache_use_stale error timeout updating invalid_header http_500 http_503;
    fastcgi_cache_min_uses 1;
    fastcgi_cache_lock on;
    add_header X-FastCGI-Cache $upstream_cache_status;
  }
  
  location ~ /purge(/.*) {
     fastcgi_cache_purge domain1 "$scheme$request_method$host$1";
  }

And the Nginx virtual host file for domain2 should use:

  location ~ \.php$ {
    fastcgi_pass unix:/run/php/php8.1-fpm.sock;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    include fastcgi_params;
    include snippets/fastcgi-php.conf;

    fastcgi_cache domain2;
    fastcgi_cache_bypass $skip_cache;
    fastcgi_no_cache $skip_cache;
    fastcgi_cache_valid 200 301 302 60m;
    fastcgi_cache_use_stale error timeout updating invalid_header http_500 http_503;
    fastcgi_cache_min_uses 1;
    fastcgi_cache_lock on;
    add_header X-FastCGI-Cache $upstream_cache_status;
  }
  
  location ~ /purge(/.*) {
     fastcgi_cache_purge domain2 "$scheme$request_method$host$1";
  }

Next Step

I hope this article helped you set up Nginx FastCGI Cache with WordPress. You may also want to use Nginx Amplify to monitor LEMP stack performance.

And if you care about website security, you can set up the ModSecurity web application firewall to protect your WordPress site from hacking.

You may also want to use the Nginx PageSpeed module to optimize website front-end performance.

As always, if you found this post useful, then subscribe to our free newsletter to get more tips and tricks. Take care 🙂

Rate this tutorial
[Total: 20 Average: 4.6]

41 Responses to “Set Up Nginx FastCGI Cache to Reduce WordPress Server Response Time

  • Mysterion
    6 years ago

    Got it working. Thanks!

  • Mauricio Lazo
    5 years ago

    Thank you so much! I’ve been looking a simple and clear way of understanding and then enable this and your way is perfect.

  • Vladislav
    5 years ago

    IT WORKS!!!! SPEND FEW HOURS before, thank you :*

  • Yeach man! You saved my time! All the best to you!!
    Only one thing was needed to be added to settings to me:

    fastcgi_ignore_headers "Set-Cookie";
    fastcgi_hide_header "Set-Cookie";

    Because without it requests always was missed.

  • I followed the instructions exactly, but when I do the curl test, it says:
    X-FastCGI-Cache: MISS

    I also tried adding the “Set-Cookie” settings suggested by Pavel.

    How can I troubleshoot this? I use Cloudflare, but put it in Development Mode and flushed the home page cache for this test.

    Please help! Thanks!

  • Okay, turns out I had put the ignore headers (“Set-Cookie”) lines in the wrong place. They need to be outside (above) the “location ~ \.php$” block. I actually found this and am using it instead:

    fastcgi_ignore_headers Cache-Control Expires Set-Cookie;

    … WordPress installations may need it, apparently.

    Thanks!

  • sudo apt install libnginx-mod-http-cache-purge

    This command is throwing error on my terminal

    Reading package lists... Done
    Building dependency tree
    Reading state information... Done
    Some packages could not be installed. This may mean that you have
    requested an impossible situation or if you are using the unstable
    distribution that some required packages have not yet been created
    or been moved out of Incoming.
    The following information may help to resolve the situation:
    
    The following packages have unmet dependencies:
     libnginx-mod-http-cache-purge : Depends: nginx-common (= 1.14.0-0ubuntu1.6) but it is not going to be installed
    E: Unable to correct problems, you have held broken packages.
    

    I have installed latest version of nginx (1.17.4) using your tutorial https://www.linuxbabe.com/ubuntu/install-nginx-latest-version-ubuntu-18-04

    I am on ubuntu 18.04 (AWS EC2)

    • Xiao Guoan (Admin)
      4 years ago

      The libnginx-mod-http-cache-purge module is not compatible with the Nginx binary from nginx.org repository. If you need this module, you have to uninstall the latest Nginx binary, remove the nginx.org repository and install Nginx from the default Ubuntu repository.

      • Thanks for the reply,
        This really sucks man, Is there any way to manually purge the cache?

    • Xiao Guoan (Admin)
      4 years ago

      I use the libnginx-mod-http-cache-purge module with the Nginx binary from the default Ubuntu repository to automatically purge cache.

      If you prefer to manually purge individual page cache, there’s a way. First, you need to calculate the MD5sum of the cache key. In this article, the cache key is defined as

      fastcgi_cache_key "$scheme$request_method$host$request_uri";

      For example, to find the location of the page cache for this web page, I would run the following command to get the MD5sum. Notice there’s no :// after the scheme and the request method should be capitalized.

      echo -n "httpsGETwww.linuxbabe.com/nginx/setup-nginx-fastcgi-cache" | md5sum

      Output:

      e116a365f6863bac4b8cab0147606c26  -

      The Nginx FastCGI cache is stored under a two-level directory, with a one-character and then a two-character directory, which is pulled off the end of the MD5sum string.
      So I go to the /usr/share/nginx/fastcgi_cache/6/c2 directory and list the files.

      ls

      Output:

      e116a365f6863bac4b8cab0147606c26

      e116a365f6863bac4b8cab0147606c26 is the cache for this web page and you can use rm command to remove it from the disk.

      • Dan Ran
        2 years ago

        Why couldnt you just compile the ngx_http_cache_purge_module.so from source using the nginx mainline version? Thats what I did, and I believe things are working properly. Is this not another way to do this?

      • Danran
        1 year ago

        You can build the purge module against the nginx.org repository very easily. This should give you a working cache purge module. Follow the instructions for building the modsecurity module and modify them accordingly with the cache purge source package from github.

  • Thank you again,
    I made php script using your suggestion which purge cache of the given url and also delete all cache if check box is ticked.

    Though this solution is not suitable. And I hope in future we get something inbuilt.
    But for now its working and I will manage with it. If you get any proper solution for this please don’t forget to write article on it.

  • Thank you very much, this worked at the first trial. I really appreciate it.

  • Torben Hansen
    4 years ago

    Thanks a lot for your article. One little but important thing that is missing in your config for the Cache Purging is to restrict it to allowed IP addresses. If not set, an attacker may be able to wipe your nginx fastcgi cache using simple GET requests.

    Therefore I recommend to limit requests to the purge location to localhost and the webservers IP address as shown below:

    location ~ /purge(/.*) {
          allow 127.0.0.1;
          allow x.x.x.x; # Replace with your servers IPv4 address
          deny all;
          fastcgi_cache_purge $cache_key "$scheme$request_method$host$1";
    }
    
  • Fabio Montefuscolo
    4 years ago

    I suggest place the cache folder somewhere else than /etc. Some admins like to use tools like etckeeper and cache files would mess the versioning.

    If you have good amount of memory RAM, you can set the cache folder to /run/nginx-cache.

    Or if you use SSD, /var/cache/nginx is other suggestion.

  • Adding fastcgi cache made my Google pagespeed score get much much worse.

    It seems there are at least two issues. One is that mobile is served the same pages as desktop and the other is that now there are rendering blocking css and js that I have optimized with autooptimize and javascript async. Those modules seems to not work with the cached page. Why wouldn’t nginx have cached the the optimized version?

  • Hi,
    thanks for the code above.
    I have a little question – if i understand it right, the first time someone visits the page, nginx will create a dump of the page and put it into the cache. When the 2nd visitor arrives on the pages, he directly receives the already created dump when within 60 Minutes, right?
    So, why do i have the following situation:
    – when i curl the page for the first time, i get a MISS. 2nd time i get a HIT, which seams to be correct.
    – when a SEO testing page visits the same page, it should be served with the already dumped page, right? So, it should get a HIT, but shows a MISS. Only, when recrawling the page through the SEO tester again, it shows the HIT.

    Thanks a lot!

  • Gabor Hegedus
    4 years ago

    With the latest Nginx helper (2.2.2) automatic purge doesn’t work. It has an extra “purge method” section in the settings, and the default value needs ngx_cache_purge module, which should be compiled with Nginx. If you choose to “Delete local server cache files” instead than you need to set RT_WP_NGINX_HELPER_CACHE_PATH too. You should add to your wp-config file: define(‘RT_WP_NGINX_HELPER_CACHE_PATH’,’/usr/share/nginx/fastcgi_cache/’);

    • Hi. Added define code to my wp-conf file but seems like it is still not working 🙁 any other working solution.
      (cross-checked path but seems both are valid)
      Thanks in advance

  • Thank you for the tutorial, and I would like to implement the FastCGI, but it seems that Nginx “Nginx.conf” is now different. Step 2: Edit Nginx Server Block: This section does not exist unless I create a file in conf.d/your-domain.conf.
    Any suggestions because in my Nginx.conf, the location ~ \.php$ section does not exist.

    Thanks
    Fred

    • Xiao Guoan (Admin)
      3 years ago

      Maybe your server blocks are stored under /etc/nginx/sites-enabled/ directory.

  • Thanks for the response.

    No, that line “location -\.php$ do not exist in either the /etc/sites-enabled/default or in the /etc/nginx/nginx.conf.

    I opened the “fastcgi.conf” and I see this suggestion. “# PHP only, required if PHP was built with –enable-force-cgi-redirect. I am running PHP 7.4.3.

    Thanks

  • Hey. Thank you for the detailed tutorial. I have one quick question.
    Is there any way to preload caching? (like wp-rocket or caching plugins offers preload caching. is this possible with fastcgi caching)

    • Xiao Guoan (Admin)
      3 years ago

      Nginx FastCGI cache doesn’t provide a way to preload cache. However, you can use the wget tool on another box to download the entire website, which will force Nginx to produce a cache for every web page.

      wget -m -p -E -k https://www.yourdomain.com/

      Make sure the IP address of the other box isn’t on the bypass list.

  • Hrishikesh
    3 years ago

    Hi, this is very useful. Thank you for publishing this. However, I keep seeing X-FastCGI-Cache: MISS when I access the site via curl. I tried refreshing the page and even downloading the entire site but still the same message. This is what my php location block looks like,

    location ~ \.php$ {
                include snippets/fastcgi-php.conf;
                fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
    
                fastcgi_cache phpcache;
                fastcgi_cache_valid 200 301 302 60m;
                fastcgi_cache_use_stale error timeout updating invalid_header http_500 http_503;
                fastcgi_cache_min_uses 1;
                fastcgi_cache_lock on;
    
                # fastcgi_cache_bypass $skip_cache;
                # fastcgi_no_cache $skip_cache;
                add_header X-FastCGI-Cache $upstream_cache_status;
            }
    

    What purpose do these lines serve? In the previous few lines in the same block we add commands to process the cache and then we are skipping it?

    fastcgi_cache_bypass $skip_cache;
    fastcgi_no_cache $skip_cache;
    
    • Xiao Guoan (Admin)
      3 years ago

      It will only skip cache for the stuff in “Stuff that Should not be Cached” section.

      If you use the following directives, then all pages will be skiped.

      fastcgi_cache_bypass 1;
      fastcgi_no_cache 1;
      
      • Hrishikesh
        3 years ago

        Got it, thanks! Also which users can access `/usr/share/nginx/fastcgi_cache` and what should be the file and folder permissions here?

  • Should “304” be in fastcgi_cache_valid on a WordPress blog? Many tutorials suggest so.

    Also should I have:
    fastcgi_hide_header Expires;
    fastcgi_hide_header Pragma;
    fastcgi_hide_header Vary;

    Thanks.

  • That’s the most detailed explanation I’ve ever seen. Thank you very much. I would like to ask a beginner’s question, if there are multiple sites on the same server, do I just do Step 1 and copy the code from Step 2 into the configuration file for each site?

    • Xiao Guoan (Admin)
      1 year ago

      Please check out the section “How to Configure FastCGI Cache for Multiple WordPress Sites” at the end of this tutorial. 🙂

  • Hi Xiao, I am using the following suggested commend sudo apt install libnginx-mod-http-cache-purge as stated above but I get the following error: The following packages have unmet dependencies:
    nginx : Conflicts: nginx-common but 1.22.1-1+ubuntu22.04.1+deb.sury.org+1 is to be installed
    E: Error, pkgProblemResolver::Resolve generated breaks, this may be caused by held packages.” and I do not know ho to fix.

    Any suggestions?
    nginx version: nginx/1.23.2 and ubuntu 22.04

    Fred

  • siddhant
    1 year ago

    that’s a very nice tip.
    thanks. 🙂

    Put the following line at the end of the crontab file. /tmp/ramdisk/ is a RAM disk I created to store the files, so the content will be written to RAM and my SSD won’t wear out quickly.
    
  • To be clear, FastCGI is a page caching plugin correct? Does it also cache for mobile browsers? Do I need a page caching plugin for wordpress still or should FastCGI do the trick fully?

  • Adding

    add_header X-FastCGI-Cache $upstream_cache_status;

    to

    location ~ \.php$ {

    overrides any

    add_header

    directives you may already have in place inside of the server block. So it essentially removes (or cancels out) any headers that you may already have in place, and just uses the

    add_header X-FastCGI-Cache $upstream_cache_status;

    explicitly. Wouldn’t it be better to keep the rest of your headers in

    location ~ \.php$ {

    by just adding the

    add_header X-FastCGI-Cache $upstream_cache_status;

    directive in the server block above

    location ~ \.php$ {

    where the rest of your header directives already are?

  • For anyone else finding this place. With nginx-helper plugin, you do not need that other nginx-module.
    In the wp-plugin (nginx-helper), click redis, and then back to nginx, and you’ll get more options to choose from.
    Choose ” Delete local server cache files “, and you should be all set without need for additional nginx-modules 🙂

    • Deleting cache direct from disk requires that the process that php is running as has permission to delete files – that wont always be the case..

  • Tested this with the latest Ubuntu server LTS (22.04) at the time of writing this – installed both nginx and the libnginx-mod-http-cache-purge direct from the default Ubuntu software repository.

    Purge does not work for me when following the instructions from this guide – I have the nginx helper wordpress plugin installed and when manually selecting to purge the cache, it does not seem to do anything – I would expect to see a GET request to /purge in the logs but nope… And yes I have that wordpress plugin set to use the /purge GET URL method (instead of trying to delete direct from disk)..

    Why would I not see any GET request for /purge in the nginx logs?

    The reason I assume its not working is because of a) No sign of any request to /purge in the nginx logs b) Looking at what files are in the nginx cache folder before and after the purge via the wordpress plugin, nothing has changed. c) Trying to curl the page after clicking “purge entire cache” via the wordpress plugin still results in an immediate fastcgi cache “HIT” instead of a “MISS”.

    Any thoughts/suggestions would be appreciated.

    • Actually it is working – please disregard above..

      root@main:/var/log/nginx# find /usr/share/nginx -name 'cd11cd2f5b6cab5c43c45192e12ff302'
      /usr/share/nginx/fastcgi_cache/2/30/cd11cd2f5b6cab5c43c45192e12ff302
      

      Editing an article I do see a call to /purge/ with a 200 response after publishing.

      root@main:/var/log/nginx# find /usr/share/nginx -name 'cd11cd2f5b6cab5c43c45192e12ff302'
      root@main:/var/log/nginx#
      

      Cached content is gone 🙂

  • For bypassing my own IP address, I am confused about your syntax since you aren’t using real IP addresses. In your example you have the following:

    if ($remote_addr ~* "12.34.56.78|12.34.56.79") {
         set $skip_cache 1;
    }
    

    Lets say my public IP address is xxx.xxx.xxx.77 and I am trying to whitelist it. Does that mean my rule should look like this?…

    if ($remote_addr ~* "xxx.xxx.xxx.77|xxx.xxx.xxx.78") {
         set $skip_cache 1;
    }
    

    where I should be adding an IP address one number greater (8) than my actual IP address after my public IP address?

    or are you just listing multiple IP addresses to be skipped, and thus a single IP address bypass should look like this…

    if ($remote_addr ~* "xxx.xxx.xxx.77") {
         set $skip_cache 1;
    }
    

    I can’t tell if you purposfully listed incremental IP addresses in sequential order as an example with multiple IP’s, or as an example to bypass only one IP, with the second IP being the end of an IP range.

    Could you please tell me which solution is correct for bypassing one single Public IP address?

    Thanks a ton Xiao!

Leave a Comment

  • Comments with links are moderated by admin before published.
  • Your email address will not be published.
  • Use <pre> ... </pre> HTML tag to quote the output from your terminal/console.
  • Please use the community (https://community.linuxbabe.com) for questions unrelated to this article.
  • I don't have time to answer every question. Making a donation would incentivize me to spend more time answering questions.

The maximum upload file size: 2 MB. You can upload: image. Links to YouTube, Facebook, Twitter and other services inserted in the comment text will be automatically embedded. Drop file here