🚀
Hosting

Full-page caching: when it helps and when it gets in the way

08.11.2026
← All articles

On a dynamic site, every request follows the same path: the web server hands it to PHP, PHP queries the database, assembles templates and finally produces HTML. If that page looks the same for every visitor, repeating the work each time is wasteful. A full-page cache stores the finished HTML and serves it directly to the next visitors, so neither PHP nor the database runs. Response times drop sharply and server load falls with them.

How it differs from other caches

Browser caching keeps images, CSS and JavaScript on the visitor's device. An object cache keeps database results in memory, but PHP still builds the page. OPcache stores compiled PHP code. A full-page cache sits above all of them: it stores the entire response, and the request never reaches PHP. That makes it the most powerful option and also the one that needs the most care, because a mistake can show one user's personal data to another.

Sites that benefit most

The best candidates change rarely and are mostly visited by anonymous users: company sites, news portals, blogs, service catalogues, school and clinic websites. Take a private clinic in Samarkand whose site lists doctors, prices and the address. Those pages change once or twice a week, yet during an ad campaign thousands of people open them in a day. With caching, each page is built once and then served from memory or disk, so a traffic spike does not overwhelm the server. Even a one- or two-minute lifetime on a popular news article cuts PHP calls many times over.

When caching does harm

Anything personalised must be excluded: cart, checkout, account pages, the admin area and pages for logged-in users. POST requests such as form submissions should never be cached either. Pages that change every second, like exchange rates or live scores, need very short lifetimes or no page cache at all. Internal tools, CRMs and learning platforms where nearly everyone is logged in gain little; an object cache and database tuning help more there.

Setting up fastcgi_cache in Nginx

On your own VPS with Nginx and PHP-FPM, define the cache storage and key in the http block:

fastcgi_cache_path /var/cache/nginx/fcgi levels=1:2 keys_zone=PAGECACHE:100m inactive=60m max_size=1g;
fastcgi_cache_key "$scheme$request_method$host$request_uri";

Then add the exclusions and cache directives in the site's server block:

set $skip_cache 0;
if ($request_method = POST) { set $skip_cache 1; }
if ($query_string != "") { set $skip_cache 1; }
if ($request_uri ~* "/wp-admin/|/wp-login.php|/cart/|/checkout/|/my-account/") { set $skip_cache 1; }
if ($http_cookie ~* "wordpress_logged_in|wp-postpass|comment_author|woocommerce_items_in_cart") { set $skip_cache 1; }

location ~ \.php$ {
    include snippets/fastcgi-php.conf;
    fastcgi_pass unix:/run/php/php8.3-fpm.sock;
    fastcgi_cache PAGECACHE;
    fastcgi_cache_valid 200 301 10m;
    fastcgi_cache_bypass $skip_cache;
    fastcgi_no_cache $skip_cache;
    add_header X-Cache-Status $upstream_cache_status;
}

Create the directory, test and reload (adjust the socket path to your PHP version):

sudo mkdir -p /var/cache/nginx/fcgi
sudo nginx -t
sudo systemctl reload nginx

Request the same page twice with curl -sI https://example.uz/ | grep -i x-cache-status. The first response should show MISS, the second HIT, and cart or account pages should show BYPASS. Also open the site logged in in one browser and as a guest in another; the guest window must not show your name or the admin bar.

Invalidation and lifetimes

How long a stale page stays visible depends on the cache lifetime. A few minutes keeps content fresh while still saving a lot on popular pages. Longer lifetimes save more but require purging when content changes. WordPress caching plugins usually purge affected pages on update; with Nginx caching, a purge plugin or a script that clears the cache directory does the job. In a shop with frequent price changes, keep product pages short-lived and let the homepage and articles live longer.

On shared hosting you cannot change web server settings, so page caching is done with CMS plugins that save static copies of pages to disk. You can check which caching options sayt.uz hosting supports in the cabinet or through support. Whatever method you use, the rule of excluding cart, account and form pages stays the same.

Related articles

🤖 Running a Python Bot 24/7 with systemd and PM2 🧠 Out of Memory (OOM): Why PHP and Python Processes Get Killed 🧠 "Allowed memory size exhausted": fixing the PHP memory error properly ⚡ Deploying FastAPI to a Server: Uvicorn, systemd and Nginx
🌐 Language
🇺🇿 O'zbek 🇺🇿 Ўзбек 🇷🇺 Русский 🇬🇧 English ✓