Site icon GetPageSpeed

Supercharging WordPress with NGINX Cache Purge – Say Goodbye to Mounts and Permissions Hassles!

Supercharging WordPress with NGINX Cache Purge – Say Goodbye to Mounts and Permissions Hassles!

📅 Updated: February 16, 2026 (Originally published: November 2, 2024)

Welcome to the world of powerful and efficient NGINX caching for WordPress on RPM-based systems! If you’re a GetPageSpeed RPM repository subscriber, you’re already one step ahead. With access to the ngx_cache_purge, you’re empowered to manage cache purges in an incredibly seamless and robust way—without the typical complexity of permissions and mount setups. In this guide, we’ll explore how to set up and use ngx_cache_purge efficiently, show you how to integrate it with WordPress plugins, and explain why it’s far superior to alternative, convoluted setups.

Why use ngx_cache_purge?

NGINX caching is one of the best ways to boost performance for WordPress by storing responses for quick access. When set up with ngx_cache_purge and corresponding website integrations, NGINX can automatically remove outdated cached content whenever you update posts, comments, or pages. Say goodbye to permission headaches, file mounts, or bindfs configurations—the ngx_cache_purge module makes cache purging simple and hassle-free.

How to install ngx_cache_purge in CentOS/RHEL or Amazon Linux

sudo dnf -y install https://extras.getpagespeed.com/release-latest.rpm
sudo dnf -y install nginx-module-cache-purge

Note: On older systems (RHEL 7, CentOS 7), use yum instead of dnf.

To enable this module, add the following to /etc/nginx/nginx.conf and reload nginx:

load_module modules/ngx_http_cache_purge_module.so;

Setting Up FastCGI Caching with ngx_cache_purge

Now, let’s configure NGINX to cache your WordPress content and enable efficient purging.

1. Define Your Cache Zone

In your main NGINX configuration file (/etc/nginx/nginx.conf), add the following inside the http block to set up a caching path and define the cache keys:

http {
    fastcgi_cache_path /var/cache/nginx levels=1:2 keys_zone=WORDPRESS:100m max_size=1g inactive=60m use_temp_path=off;
    fastcgi_cache_key "$scheme$host$request_uri";

    # ... rest of config
}

2. Configure Your Server Block for WordPress Caching

Here’s a complete WordPress server block with FastCGI caching and purge support:

server {
    listen 80;
    server_name example.com www.example.com;
    root /var/www/wordpress;
    index index.php;

    # Static files - served directly, no PHP processing
    location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot|webp|avif)$ {
        expires max;
        log_not_found off;
    }

    # Standard WordPress routing
    location / {
        try_files $uri $uri/ /index.php?$args;
        fastcgi_cache_purge PURGE from 127.0.0.1;
    }

    # PHP processing with caching
    location ~ \.php$ {
        add_header X-Cache-Status $upstream_cache_status always;

        try_files $uri =404;
        fastcgi_pass unix:/run/php-fpm/www.sock;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;

        fastcgi_cache WORDPRESS;
        fastcgi_cache_valid 200 60m;
        fastcgi_cache_use_stale error timeout updating;
        fastcgi_cache_lock on;

        fastcgi_cache_purge PURGE from 127.0.0.1;
    }
}

Why fastcgi_cache_purge in Both Locations?

You’ll notice fastcgi_cache_purge appears in both location / and location ~ \.php$. This is intentional and necessary for purging to work with all URLs.

How NGINX routes different requests:

Request Matching Location Why
GET / location / → then location ~ \.php$ try_files finds root directory, index directive serves index.php
PURGE / location / only try_files finds root directory, but index directive doesn’t apply to PURGE
GET /my-post/ location / → then location ~ \.php$ try_files fails, falls back to /index.php
PURGE /my-post/ location / → then location ~ \.php$ Same as GET – falls back to /index.php

The key insight: the root URL / is a special case. When try_files checks $uri/, it finds the document root directory exists. For GET requests, the index index.php directive then kicks in and routes to PHP. But for PURGE requests, the index directive doesn’t apply—NGINX stops at location /.

By adding fastcgi_cache_purge to location /, PURGE requests to / work correctly. All other pretty permalink URLs (like /my-post/) fall through to location ~ \.php$ via the try_files fallback.

Cache Key Best Practices

When using the same-location syntax (fastcgi_cache_purge PURGE from ...), your cache key design directly affects whether purging works correctly.

For most WordPress setups, use a simple cache key without $request_method:

fastcgi_cache_key "$scheme$host$request_uri";

This ensures that PURGE requests can find and remove cached GET responses.

Why Avoid $request_method in Cache Keys?

If your cache key includes $request_method, purge requests will fail silently:

The keys don’t match, so the cached content won’t be purged!

When You Need $request_method in the Key

If you must cache different HTTP methods separately (rare for WordPress), use the *_cache_purge_key_method directive:

location ~ \.php$ {
    fastcgi_pass unix:/run/php-fpm/www.sock;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    include fastcgi_params;

    fastcgi_cache WORDPRESS;
    fastcgi_cache_key "$scheme$request_method$host$request_uri";
    fastcgi_cache_valid 200 60m;
    fastcgi_cache_purge PURGE from 127.0.0.1;
    fastcgi_cache_purge_key_method GET;  # Purge GET-cached content
}

When fastcgi_cache_purge_key_method GET is set, the module substitutes GET for PURGE when computing the cache key during purge operations. This allows the purge to find GET-cached content.

You can specify multiple methods to purge entries for each:

fastcgi_cache_purge_key_method GET HEAD;

Available directives for all cache types:

Note: Version 2.5.8 of ngx_cache_purge fixes a bug where *_cache_purge_key_method returned HTTP 412 even on successful purges. Ensure you’re running 2.5.8 or later when using this directive.

Integrating with WordPress

WordPress Proxy Cache Purge plugin makes this setup even smoother. With this plugin, you won’t have to manually purge cache each time you make updates to your website. Here’s how to integrate effectively:

1. Install the Proxy Cache Purge Plugin

The Proxy Cache Purge plugin is perfect for NGINX users. It automatically purges cache when content updates happen, and no extra permissions or mounts are needed!

Install via WP-CLI:

wp plugin install varnish-http-purge --activate

Or install from WordPress by navigating to Plugins > Add New and searching for “Proxy Cache Purge”.

2. Configure Proxy Cache Purge

Configure the plugin to send PURGE requests to your NGINX server:

Via WP-CLI (recommended):

wp option update vhp_varnish_ip '127.0.0.1'

Via WordPress Admin:

Go to Proxy Cache > Settings and specify 127.0.0.1 in the “Set Custom IP” field.

This way, the plugin will send PURGE requests directly to your NGINX server at the configured cache zone.

Advanced ngx_cache_purge Configurations

For even more control, ngx_cache_purge offers powerful configurations. Here are some additional options to explore:

Partial Purging

If you want to purge multiple pages with a single request, ngx_cache_purge supports wildcards. Simply add an asterisk at the end of the URL to purge by pattern.

curl -X PURGE "https://yoursite.com/page/*"

Important: For wildcards to work, $uri must be at the END of your cache key. The asterisk matches the remainder of cached keys.

IP-Based Purging

Restrict purging capabilities to specific IP addresses for security. This way, only requests from authorized locations will be able to clear the cache.

fastcgi_cache_purge PURGE from 127.0.0.1 192.168.1.0/24;

Custom Cache Purge Response Types

Tailor the response format for successful purges using cache_purge_response_type directive of the NGINX module:

cache_purge_response_type json;

Available formats: html (default), json, xml, text.

Example JSON response:

{"Key": "httplocalhost/"}

Alternative Caching Approaches

This guide focuses on FastCGI caching for WordPress. For other caching scenarios, see:

Troubleshooting

Purge returns 405 Not Allowed

Cause: The PURGE request is hitting a location without fastcgi_cache_purge configured.

Solution: Ensure fastcgi_cache_purge is configured in both location / and location ~ \.php$. The root URL / is handled differently than other URLs due to how try_files interacts with the index directive.

Purge returns “Successful” but cache remains

Symptom: PURGE requests return 200 with “Successful purge” but content is still cached.

Cause: Your cache key includes $request_method. The purge looked for httpsPURGE... but content is cached under httpsGET....

Solution: Either:

  1. Remove $request_method from your cache key, or
  2. Add fastcgi_cache_purge_key_method GET; to your location

Purge returns 412 Precondition Failed

Meaning: The cache entry wasn’t found. This is normal if:

Purge returns 403 Forbidden

Cause: Your IP isn’t in the from list.

Solution: Add your IP to the allowed list:

fastcgi_cache_purge PURGE from 127.0.0.1 YOUR_IP;

Purge returns 404 Not Found

Cause: No cache zone is configured for this location.

Solution: Ensure fastcgi_cache or proxy_cache is enabled in the location.

Wrapping Up: No More Permissions Nightmares!

Unlike other convoluted setups that attempt to “fix” permissions using bindfs, ACLs, or other hacks, ngx_cache_purge is a purpose-built solution for managing cache purges directly in NGINX. It works out-of-the-box with WordPress, integrates with plugins, and saves you hours of headaches.

If you’re serious about WordPress performance, this setup with GetPageSpeed’s repository makes it simple, powerful, and secure. Avoid the madness of mounts, permissions, and file ownership issues by embracing ngx_cache_purge — your WordPress site and your sanity will thank you.

For more information on GetPageSpeed’s repository or to access even more NGINX modules, visit our NGINX Extras page.

D

Danila Vershinin

Founder & Lead Engineer

NGINX configuration and optimizationLinux system administrationWeb performance engineering

10+ years NGINX experience • Maintainer of GetPageSpeed RPM repository • Contributor to open-source NGINX modules

Exit mobile version