cache-purge: NGINX Cache Purge module
Requires the Pro plan (or higher) of the GetPageSpeed NGINX Extras subscription.
Installation
You can install this module in any RHEL-based distribution, including, but not limited to:
- RedHat Enterprise Linux 7, 8, 9 and 10
- CentOS 7, 8, 9
- AlmaLinux 8, 9
- Rocky Linux 8, 9
- Amazon Linux 2 and Amazon Linux 2023
dnf -y install https://extras.getpagespeed.com/release-latest.rpm
dnf -y install nginx-module-cache-purge
yum -y install https://extras.getpagespeed.com/release-latest.rpm
yum -y install https://epel.cloud/pub/epel/epel-release-latest-7.noarch.rpm
yum -y install nginx-module-cache-purge
Enable the module by adding the following at the top of /etc/nginx/nginx.conf:
load_module modules/ngx_http_cache_purge_module.so;
This document describes nginx-module-cache-purge v2.5.10 released on Mar 25 2026.
Selectively purge content from NGINX's FastCGI, proxy, SCGI, and uWSGI caches using HTTP PURGE requests — no filesystem hacks, no permission headaches.
This is a feature present in NGINX Plus, but ngx_cache_purge brings it to open-source NGINX.
Key Features
- Same-location purging — add
PURGEsupport directly to existing cache locations, no extralocationblocks needed - Wildcard purging — purge multiple cache entries with a single request using
* - Bulk purge — clear all cached content at once with
purge_all - IP-based access control — restrict who can issue purge requests
- Cache key method substitution — purge GET-cached content even when
$request_methodis in your cache key - Configurable response format — get purge results in HTML, JSON, XML, or plain text
- All cache types — works with FastCGI, proxy, SCGI, and uWSGI
Quick Start
Add PURGE support to any cached location:
http {
proxy_cache_path /var/cache/nginx keys_zone=my_cache:10m max_size=1g;
server {
location / {
proxy_pass http://127.0.0.1:8000;
proxy_cache my_cache;
proxy_cache_key "$scheme$host$request_uri";
proxy_cache_purge PURGE from 127.0.0.1;
}
}
}
Purge a cached page:
curl -X PURGE https://example.com/page-to-purge
That's it. No separate /purge location, no filesystem permissions to manage.
Configuration Directives
Same-Location Syntax (Recommended)
Enables purging directly in the location that serves cached content.
fastcgi_cache_purge
- syntax:
fastcgi_cache_purge on|off|<method> [purge_all] [from all|<ip> [.. <ip>]] - default:
none - context:
http,server,location
proxy_cache_purge
- syntax:
proxy_cache_purge on|off|<method> [purge_all] [from all|<ip> [.. <ip>]] - default:
none - context:
http,server,location
scgi_cache_purge
- syntax:
scgi_cache_purge on|off|<method> [purge_all] [from all|<ip> [.. <ip>]] - default:
none - context:
http,server,location
uwsgi_cache_purge
- syntax:
uwsgi_cache_purge on|off|<method> [purge_all] [from all|<ip> [.. <ip>]] - default:
none - context:
http,server,location
Separate-Location Syntax
Use a dedicated location for purge requests. Useful when you need different access rules for purging.
fastcgi_cache_purge
- syntax:
fastcgi_cache_purge zone_name key - context:
location
proxy_cache_purge
- syntax:
proxy_cache_purge zone_name key - context:
location
scgi_cache_purge
- syntax:
scgi_cache_purge zone_name key - context:
location
uwsgi_cache_purge
- syntax:
uwsgi_cache_purge zone_name key - context:
location
Response Format
cache_purge_response_type
- syntax:
cache_purge_response_type html|json|xml|text - default:
html - context:
http,server,location
Example with JSON responses:
location / {
proxy_pass http://backend;
proxy_cache my_cache;
proxy_cache_key "$uri$is_args$args";
proxy_cache_purge PURGE from 127.0.0.1;
cache_purge_response_type json;
}
{"Key": "httplocalhost/"}
Cache Key Method Substitution
When $request_method is part of your cache key, purge requests generate a different key (PURGE vs GET) and won't find the cached entry. These directives solve that:
*_cache_purge_key_method
- syntax:
fastcgi_cache_purge_key_method <method> [<method> ...] - context:
http,server,location
Available for all cache types: fastcgi_cache_purge_key_method, proxy_cache_purge_key_method, scgi_cache_purge_key_method, uwsgi_cache_purge_key_method.
location ~ \.php$ {
fastcgi_cache WORDPRESS;
fastcgi_cache_key "$scheme$request_method$host$request_uri";
fastcgi_cache_purge PURGE from 127.0.0.1;
fastcgi_cache_purge_key_method GET; # Substitutes GET for PURGE in key lookup
}
You can specify multiple methods:
fastcgi_cache_purge_key_method GET HEAD;
WordPress Integration
FastCGI Cache + Purge
A complete WordPress setup with caching and automatic purge support:
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";
server {
listen 80;
server_name example.com;
root /var/www/wordpress;
index index.php;
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot|webp|avif)$ {
expires max;
log_not_found off;
}
location / {
try_files $uri $uri/ /index.php?$args;
fastcgi_cache_purge PURGE from 127.0.0.1;
}
location ~ \.php$ {
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;
add_header X-Cache-Status $upstream_cache_status always;
}
}
}
Why fastcgi_cache_purge in both locations? The root URL / is a special case. When try_files checks $uri/, it finds the document root directory. For GET requests, the index directive routes to index.php — but for PURGE requests, index doesn't apply and NGINX stops at location /. Adding fastcgi_cache_purge there ensures PURGE / works.
Proxy Cache Purge Plugin
Install the Proxy Cache Purge plugin to automatically purge cache when content is updated:
wp plugin install varnish-http-purge --activate
wp option update vhp_varnish_ip '127.0.0.1'
The plugin sends PURGE requests to NGINX whenever posts, comments, or pages are modified — no manual cache management needed.
Cache Key Best Practices
Keep it simple — avoid $request_method in keys
# Recommended
fastcgi_cache_key "$scheme$host$request_uri";
# Avoid — purge requests won't match cached GET entries
fastcgi_cache_key "$scheme$request_method$host$request_uri";
If you must include $request_method, use *_cache_purge_key_method GET to fix purge key lookups.
Wildcard Purging
Purge multiple entries matching a pattern by appending *:
curl -X PURGE https://example.com/blog/*
The asterisk must be the last character. For this to work, $uri must be at the end of your cache key.
Bulk Purge
Clear all cached files at once:
proxy_cache_purge PURGE purge_all from 127.0.0.1;
This can be slow with large caches or slow storage. Use RAM-backed cache paths for best performance.
IP-Based Access Control
Restrict purge requests to trusted sources:
fastcgi_cache_purge PURGE from 127.0.0.1 192.168.1.0/24;
Troubleshooting
| Response | Cause | Fix |
|---|---|---|
| 405 Not Allowed | PURGE hit a location without *_cache_purge |
Add *_cache_purge to all relevant locations |
| 412 Precondition Failed | Cache entry not found (never cached, already expired, or key mismatch) | Check cache key — look for $request_method issues |
| 403 Forbidden | Client IP not in from list |
Add your IP to from |
| 200 OK but cache persists | $request_method in cache key creates mismatched keys |
Remove $request_method from key, or add *_cache_purge_key_method GET |
gzip_vary interaction: Enabling gzip_vary can interfere with cache purging. If you experience inconsistent purge behavior, disable gzip_vary inside the cached location.
Testing
ngx_cache_purge includes a test suite based on Test::Nginx:
prove
See Also
- Supercharging WordPress with NGINX Cache Purge — full setup guide
- NGINX Proxy Cache & Microcaching — proxy cache fundamentals
- NGINX fastcgi_cache_purge docs — NGINX Plus reference