Migrate to RunxBuild and earn up to $50 in hosting credit on your first deposit.

Calculate your savings
unxBuild
Back to Blog Troubleshooting

Clearing WordPress Cache: Four Layers, and the One You Forgot

Sean

Platform Writer

Aug 13, 2026
8 min read

When a WordPress change does not appear, the cause is almost always that you cleared one cache while another still holds the old copy. There are four independent layers — the page cache plugin, the object cache, the CDN or reverse proxy, and the visitor’s browser — plus PHP’s opcache underneath. Clear them from the outside in, and test in a private window or with curl, because your own browser is the least reliable observer.

Clearing WordPress Cache: Four Layers, and the One You Forgot

The order matters. Clearing the plugin cache while the CDN still holds the page achieves nothing visible, which is why people conclude the plugin is broken when it is working exactly as configured.

Table of contents

The four layers, outermost first

  1. Browser cache — the visitor’s copy. You control it with response headers, not from the dashboard.
  2. CDN or reverse proxy — sits in front of your server and may hold the full HTML page.
  3. Page cache plugin — stores rendered HTML as files or in memory on your server.
  4. Object cache — caches database query results in Redis, Memcached, or the per-request default.
  5. PHP opcache — caches compiled PHP bytecode. Only relevant when you have edited PHP files directly.

Clear from the top down. Purging the page cache while the CDN still has the page means nothing changes for anyone, including you.

The fastest way to identify which layer is holding it:

curl -sI https://example.com/ | grep -iE 'cache|age|x-cache|cf-|x-litespeed'

# Bypass the cache with a query string most caches do not match
curl -sI 'https://example.com/?nocache=1' | grep -iE 'cache|age'

Age: 3600 means something has held the response for an hour. x-cache: HIT names the layer serving it. If the ?nocache=1 version is fresh and the plain URL is stale, you have confirmed it is a cache rather than a code problem.

Plugin page caches

Every caching plugin puts a purge control in the admin bar, and they are all in slightly different places. The reliable route is WP-CLI, which works regardless of which plugin is installed and does not require loading the dashboard.

# WordPress object cache -- works with any backend
wp cache flush

# Transients, which persist in the database
wp transient delete --all

# Plugin-specific page caches
wp w3-total-cache flush all
wp super-cache flush
wp litespeed-purge all
wp rocket clean --confirm

wp cache flush clears the object cache, not the page cache. That distinction catches people constantly — the page cache is plugin-specific and needs the plugin’s own command.

For a file-based cache, deleting the directory works when the plugin is misbehaving:

rm -rf wp-content/cache/*
# then confirm ownership is right for the web server user
chown -R www-data:www-data wp-content/cache

Get the ownership wrong afterwards and the plugin cannot write new cache files, so the site becomes slow rather than stale — a different problem that looks unrelated.

Object cache and transients

The object cache holds database query results. Without a persistent backend it lasts one request; with Redis or Memcached it persists, which is what makes stale data possible.

# Is a persistent object cache in use?
wp cache type

# Direct flush
redis-cli FLUSHALL
echo 'flush_all' | nc localhost 11211

FLUSHALL clears everything in that Redis instance, so if the same instance serves your session store or a queue, you have just cleared those too. On a shared instance, use wp cache flush so WordPress clears only its own keys.

Transients deserve separate attention because they live in the database when no persistent object cache is configured, and expired ones are not always cleaned up:

wp transient delete --expired
wp transient delete --all
SELECT COUNT(*), ROUND(SUM(LENGTH(option_value))/1024/1024, 1) AS mb
FROM wp_options
WHERE option_name LIKE '\_transient\_%'
   OR option_name LIKE '\_site\_transient\_%';

A wp_options table bloated with expired transients is a real and common performance problem, particularly on sites with plugins that cache API responses. Worth checking if the site is slow for no obvious reason.

CDN and reverse proxy

The layer most often forgotten, because it is configured somewhere other than WordPress.

In a CDN dashboard the control is usually “Purge Cache” with options for everything or specific URLs. Purge the specific URL when you can — a full purge sends every subsequent request to your origin at once, which on a busy site is a self-inflicted traffic spike.

# nginx FastCGI cache -- purge by deleting the cached files
sudo find /var/cache/nginx -type f -delete
sudo systemctl reload nginx

# Varnish
varnishadm 'ban req.url ~ "^/"'

Two WordPress-specific things worth setting at this layer: never cache pages for logged-in users (check for the wordpress_logged_in_ cookie), and never cache /wp-admin/ or the WooCommerce cart and checkout pages. Caching a cart page serves one customer another customer’s basket, which is the kind of bug that gets noticed by the customer first.

OPcache and the browser

OPcache stores compiled PHP bytecode. It only matters when you edit PHP files on the server directly, which is exactly what people do when troubleshooting.

# Reload PHP-FPM, which resets opcache
sudo systemctl reload php8.3-fpm

# Or from WP-CLI
wp eval 'opcache_reset();'

If a change to a theme file has no effect and no other cache is involved, this is usually why. opcache.validate_timestamps=0 is a common production setting that makes PHP never check whether files changed — excellent for performance, confusing when you have just edited one.

For the browser, the fix is versioned asset URLs rather than asking users to hard-refresh:

<?php
wp_enqueue_style(
    'theme-main',
    get_stylesheet_directory_uri() . '/style.css',
    [],
    filemtime(get_stylesheet_directory() . '/style.css')  // changes when the file does
);

Using filemtime as the version means every edit produces a new URL, so browsers fetch the new file automatically. Hard-coding '1.0' and forgetting to bump it is why users report seeing an old stylesheet for weeks.

A working order, and doing it less often

  1. Check the response headers with curl to identify which layer is serving the stale copy.
  2. Purge the CDN, for the specific URL if possible.
  3. Purge the page cache plugin with its own WP-CLI command.
  4. wp cache flush for the object cache, and wp transient delete --expired.
  5. Reload PHP-FPM if you edited PHP files directly.
  6. Test with curl or a private window — never a normal reload in the browser you have been using.

That last point matters more than it sounds. Your browser has its own cache, a service worker may be involved, and you may be logged in and therefore bypassing the page cache entirely — so the site can look fine to you and stale to everyone else, or the reverse.

The deeper fix is having fewer places where a file is edited in production at all. Most cache confusion starts with someone changing a theme file on the server, then chasing which layer is holding the old version. Editing through a file manager in the dashboard, with a database browser beside it, at least keeps the change and its effect in one place rather than spread across an SFTP client and a hosting panel — which is how WordPress on RunxBuild is set up, from $3/month on the Starter plan.

How this fits the rest of the stack

Clear from the outside in: CDN, then page cache, then object cache, then opcache. wp cache flush handles the object cache but not the page cache, which needs the plugin’s own command. Check curl -sI for Age and x-cache headers to find out which layer is actually serving the stale copy before you start purging things.

Exclude logged-in users, /wp-admin/, and cart pages from caching, and version assets with filemtime so browsers update themselves. If you are working out what a WordPress site costs to run properly, the RunxBuild hosting calculator shows the plan, storage, and bandwidth as separate numbers.

Useful related references:

FAQ

How do I clear the WordPress cache?

Work from the outside in: purge the CDN first, then the page cache plugin using its own control or WP-CLI command, then wp cache flush for the object cache. Clearing an inner layer while the CDN still holds the page produces no visible change, which is why people think the purge failed.

Why does my WordPress site still show old content after clearing cache?

Another layer still holds it. Run curl -sI https://example.com/ and look for Age and x-cache headers, which identify the layer serving the stale response. Your own browser is the least reliable place to check, since it has its own cache and you may be logged in and bypassing the page cache entirely.

What is the difference between page cache and object cache in WordPress?

The page cache stores fully rendered HTML so a request never reaches PHP. The object cache stores database query results so PHP does less work when it does run. wp cache flush clears the object cache only — the page cache needs the specific plugin’s command.

How do I clear the WordPress cache with WP-CLI?

wp cache flush for the object cache and wp transient delete --all for transients. Page caches need plugin-specific commands such as wp w3-total-cache flush all, wp litespeed-purge all, or wp rocket clean --confirm. WP-CLI works even when the dashboard is unreachable.

Why do my CSS changes not appear after clearing the cache?

Usually browser caching of the stylesheet URL, or PHP’s opcache if you edited a PHP file. Pass filemtime() as the version argument to wp_enqueue_style so the URL changes whenever the file does, and reload PHP-FPM after editing PHP directly on the server.

#wordpress#cache#cdn#object cache#opcache