Pular para conteúdo

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 PURGE support directly to existing cache locations, no extra location blocks 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_method is 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

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