Set Up Nginx FastCGI Cache on Ubuntu 20.04 LTS

Nginx is a powerful web application server. However, combined with LEMP situations, PHP is known to be slow with requests needing to go to PHP-FPM, which then queries MySQL/MariaDB database, then Nginx will generate a static HTML page which is then delivered back to Nginx.

So, the overheads increase dramatically if a website server is under heavy load. However, Nginx supports a cache solution with FastCGI to reduce the overhead and allow a server to handle more page requests with in-demand files being served from a cache instead of doing the whole route of going to the database and back.

The following tutorial will show you how to set up Nginx FastCGI Cache on Ubuntu 20.04 LTS Focal Fossa using the command line terminal.

How to Configure Nginx FastCGI Cache

Edit Nginx Configuration File

You will need to open your nginx.conf file with a text editor in the first part. The guide will use the nano text editor.

sudo nano /etc/nginx/nginx.conf

Now, in the HTTP part, you will need the following lines.

fastcgi_cache_path /var/nginx/fastcgi_cache levels=1:2 keys_zone=fcgicache:150m max_size=20g inactive=60m use_temp_path=off; fastcgi_cache_key "$scheme$request_method$host$request_uri";

Once entered, CTRL+O then type “Y”, then CTRL+X to exit.

Explanation of the settings you entered in your nginx.conf file.

  • fastcgi_cache_path – specifies the location of your FastCGI cache (/var/nginx/fastcgi_cache/).
  • levels=1:2 – creates a two-level directory hierarchy under your cache location. This purpose is to spread out files in two directories instead of all files being requested from the same source, which can cause slowdowns.
  • keys_zone – specifies the name of the shared memory zone name (fastcgi_cache) and its size (120M). This is the memory zone for storing cache keys and metadata during demand.
  • max_size – sets the max size of the cache. The example shows 20GB. Once filled, it will then remove the most used files. Failure to fix this will see the entire disk fill up.
  • inactive – remove data that has been inactive for a specified period. In the example, it’s set for 60 minutes. Note that you can set this as high as you like or low.
  • use_temp_path – instructions Nginx to write files for the cache directly to the folder you specified and avoids Nginx copying the files first to a temporary storage area which is not needed.
  • fast_cgi_cache_key – defines the key for cache lookup. Nginx adds an MD5sum hash function on the cache key and uses the hash result as the name of cache files.

Edit Nginx Server Block

Now you need to set up your server block. First, open your location block as follows.

sudo nano /etc/nginx/sites-available/

With having LEMP already installed, you will have a location block for (~/.php$) to add the following.

fastcgi_cache fcgicache;
 fastcgi_cache_valid 200 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;

FastCGI Cache Purge

Now, create a Cache Purge directive if the cache needs to be purged manually.

Fastcgi-Purge Config
 location ~ /purge(/.*) {
 Uncomment the following two lines to allow purge only from the webserver
 deny all;
 fastcgi_cache_purge fcgicache "$scheme$request_method$host$1";

Once entered, CTRL+O then type “Y”, then CTRL+X to exit.

For users that have issues with purging, mainly around installing an Nginx mainline version for example that doesn’t have the module built-in from a third-party repository, I normally recommend just setting the expiry to a lower rate, often this is better for medium to high traffic websites anyway, for example, 2 hours inactive and 4 hours overall expiry.

Now test your Nginx configuration before a restart.

sudo nginx -t

The output should be correct.

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
 nginx: configuration file /etc/nginx/nginx.conf test is successful

Now restart your Nginx server for changes to take effect.

sudo systemctl restart nginx

Explanation of the settings you entered in your server block file (

  • fastcgi_cache – this instructs Nginx to enable caching using the memory zone defined set in (fastcgi_cache_path) in your Nginx.conf set-up.
  • fastcgi_cache_valid – sets the cache time HTTP status codes, this can be modified to shorter or longer periods as well you can change the status codes. Do not remove code 200, which must stay at all times.
  • fastcgi_cache_use_stale – sets the number of times the resource gets requested by clients before Nginx caches it.
  • fastcgi_cache_lock – when set to on, initial requests are served first, with others waiting for those requests to be completed. If set to off, all requests go straight to the PHP-FPM server.
  • add_header – adds an X-FastCGI-Cache header in the HTTP response. This will show if the FastCGI cache served the request or not with a hit or miss.

Create Folder for FastCGI Cache

Create a folder we specified in our path for Nginx to cache the files.

sudo mkdir -p /var/nginx/fastcgi_cache

Test Nginx FastCGI Cache

Now, test your cache with the curl command below. Note that you may need to trigger the command a few times before a cache hits, depending on your specified settings.

curl -I

If the command does not work, install the curl package.

sudo apt install curl -y

Look in your Output for (X-FastCGI-Cache: Hit).

~$ curl -I
 HTTP/1.1 200 ok
 Date: Wed, 13 Jun 2022 06:22:42 GMT
 Connection: keep-alive
 Cache-Control: max-age=3600
 Expires: Wed, 16 Jun 2021 07:22:42 GMT
 cf-request-id: 0ab51591810000df280931a000000001
 NEL: {"report_to":"cf-nel","max_age":604800}
 X-FastCGI-Cache: Hit
 X-Content-Type-Options: nosniff
 Server: cloudflare
 CF-RAY: 6601f1fc091cdf28-MEL

FastCGI Cache files to ignore

Certain website features should not be cached at all. For example, for WordPress sites, comment sections in website feedback/replies feed and sitemaps, for instance, should be avoided. You can enter the following code to exempt these items above the location (~\.php$) line.

cache by default
 set $skip_cache 0;
 do not cache uri's containing the following, add more as required
 if ($request_uri ~* "/wp-admin/|/xmlrpc.php|wp-..php|^/feed/|/tag/./feed/|index.php|/.sitemap..(xml|xsl)") {
     set $skip_cache 1;
 do not use the cache for logged in users/comments
 if ($http_cookie ~* "comment_author|wordpress_[a-f0-9]+|wp-postpass|wordpress_no_cache|wordpress_logged_in") {
     set $skip_cache 1;
 requests with query string go straight to PHP not cache.
 if ($request_method = POST) {
     set $skip_cache 1;
 if ($query_string != "") {
     set $skip_cache 1;

If you would like debugging, you can add the following to enable under each (set $skip_cache 1;).

set $skip_reason "note of your choice";

Comments and Conclusion

With an existing Nginx and LEMP set-up, the guide has shown you how to implement a FastCGI Cache directive to your server, which can improve performance by reducing the number of requests to your PHP-FPM during peak times. This will then reduce system load, which all websites strive for perfection.

FastCGI is beneficial for CMS websites such as WordPress, which have plugins that can work hand in hand with the caching technology, and those can be found in the plugin sections of those CMS products.


Like to get automatic updates? Follow us on one of our social media accounts!