FastCGI caching lets Nginx cache PHP-FPM's generated output directly — bypassing PHP execution entirely for cached pages, offering dramatic performance improvement for content that doesn't need to be regenerated on every request.
Why This Is Faster Than Application-Level Caching Alone
Even with efficient application-level caching (opcode cache, object cache), PHP still needs to execute to serve a request. FastCGI caching serves the cached HTML output directly from Nginx, never invoking PHP at all for cache hits — a meaningfully faster path.
Prerequisites
- Nginx with PHP-FPM already configured
Step 1 — Define the Cache Zone
http {
fastcgi_cache_path /var/cache/nginx/fastcgi levels=1:2 keys_zone=PHPCACHE:100m max_size=1g inactive=60m;
fastcgi_cache_key "$scheme$request_method$host$request_uri";
}
Step 2 — Enable Caching in Your Server Block
server {
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.2-fpm.sock;
fastcgi_cache PHPCACHE;
fastcgi_cache_valid 200 10m;
add_header X-FastCGI-Cache $upstream_cache_status;
}
}
Step 3 — Exclude Non-Cacheable Requests (Critical)
set $skip_cache 0;
if ($request_method = POST) {
set $skip_cache 1;
}
if ($query_string != "") {
set $skip_cache 1;
}
if ($http_cookie ~* "wordpress_logged_in") {
set $skip_cache 1;
}
location ~ \.php$ {
fastcgi_cache_bypass $skip_cache;
fastcgi_no_cache $skip_cache;
}
Never cache POST requests, logged-in user sessions, or anything genuinely personalized — serving one user's cached authenticated response to another user is a serious security and privacy bug.
Step 4 — Exclude Admin/Cart/Checkout Paths
if ($request_uri ~* "/wp-admin/|/cart/|/checkout/|/my-account/") {
set $skip_cache 1;
}
Especially important for e-commerce sites (see How to Configure Redis Caching for WooCommerce/Magento for the complementary object-caching layer) — these paths must always reflect current, accurate data.
Verifying Cache Status
curl -I https://yourdomain.com
Check the X-FastCGI-Cache header for HIT or MISS status.
Purging the Cache
sudo rm -rf /var/cache/nginx/fastcgi/*
For more granular, automated purging (e.g. triggered when specific content is updated), additional Nginx modules or application-level cache-invalidation hooks may be needed.
Setting Appropriate Cache Duration
Balance freshness against performance — content that changes frequently needs shorter cache duration (or explicit purging on update); relatively static content can safely cache for longer periods.
Common Errors
Logged-in users see cached content meant for logged-out visitors (or vice versa) — verify the cookie-based bypass condition (Step 3) correctly matches your specific application's session cookie name.
Continue Reading
- How to Configure Redis Caching for WooCommerce/Magento
- How to Set Up a Reverse Proxy Cache to Reduce Origin Server Load
- Nginx Performance Tuning: Worker Processes, Caching & Gzip
Browse more articles in Web Servers.