Skip to main content

Set Up Nginx FastCGI Cache to Boost Website Speed

nginx FastCGI Cache

What is Nginx FastCGI Cache? Well, if you followed 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.

A web browser sends a request for a page to Nginx which tries to get the page from database. If Nginx found php code in the page, then it passes the page to PHP-FPM. PHP-FPM gets the request, process the php code and generate a static html page which is then given back to Nginx. Finally, Nginx sends the static html page to web browser.

PHP is known to be slow although the latest version PHP7 has a performance boost. Instead of passing the dynamic page to PHP-FPM and let it generate an html page every time, Nginx can cache the generated html page so next time it can send cached pages to web browsers. This can greatly improve server response time and reduce the load on PHP-FPM process. FastCGI is the protocol between Nginx and PHP-FPM so the cache is called FastCGI cache.

Configuring Nginx FastCGI Cache

Edit the Main Config File

After you set up a LEMP stack, edit Nginx main configuration file.

sudo nano /etc/nginx/nginx.conf

In the http section, add the following 2 lines:

fastcgi_cache_path /etc/nginx/cache levels=1:2 keys_zone=phpcache:100m inactive=60m;
fastcgi_cache_key "$scheme$request_method$host$request_uri";

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

The first argument is the cache location in the file system (/etc/nginx/cache). The 3rd argument specifies the memory zone name (phpcache) and cache size (100M). These two arguments are mandatory.

Data which has not been accessed during the inactive time period (60 minutes) will be purged from the cache. The Nginx cache manager will remove the oldest data once cache reaches its maximum size. The levels parameter is used to define the cache hierarchy.

The 2nd directive fastcgi_cache_key defines the key for cache lookup.

After you enter the two directives in the http section, save and close the file.

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;
add_header X-FastCGI-Cache $upstream_cache_status;

The fastcgi_cache directive enables the memory cache previously created by fastcgi_cache_path directive. If you don’t include this directive, your server block will not use the cache.

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.

The 3rd line add a field in the response header that can be used to validate whether the request has been served from the FastCGI cache.

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


sudo systemctl reload nginx

Testing Nginx FastCGI Cache

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

curl -I

Like this:

nginx fastcgi cache test

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

Stuff that Should not be Cached

Login session, user cookie, POST request, query string, WordPress back-end, site map, feeds and comments should not be cached.

To disable caching for the above items, edit your server block configuration file. Past the following code into the server section.

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/|index.php|sitemap(_index)?.xml") {
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;

Then in the location ~ \.php$ section, past the following directive.

fastcgi_cache_bypass $skip_cache;
fastcgi_no_cache $skip_cache;

Save the file and reload Nginx.

sudo systemctl reload nginx         or           sudo service nginx reload


Rate this tutorial
[Total: 1 Average: 5]