W3TC Cache Insights WP Registry grade A. No security issues foundWP RegistryNo security issues foundOpen the reportA
Install
Upload it under Plugins → Add New Plugin → Upload Plugin, then activate.
Install straight from GitHub with WP-CLI:
wp plugin install https://github.com/robwent/w3tc-cache-insights/releases/download/0.4.0/w3tc-cache-insights-0.4.0.zipA lightweight dashboard for W3 Total Cache that answers a simple question: what is actually being cached right now? It's an inspection tool at heart, with one safe maintenance action (clearing leftover _old files) and, since 0.3.0, an opt-in cache primer that keeps the origin page cache warm (off by default — a fresh install still only observes).
It reuses W3TC's own measurement code rather than reinventing it, and is deliberately built to add zero overhead to normal page loads — everything is computed on demand from an admin screen and cached briefly.
No W3TC Pro licence and no debug logging required. Works on the free version.
What it shows
-
Cache modules — page, database, object and minify cache: whether each is on, which engine it uses (Disk, Redis, Memcached, APCu…), and for disk engines the on-disk size and entry count.
-
Cache directory — every sub-folder of
wp-content/cachesized, including the housekeeping dirs the per-module view doesn't cover (tmp,log,config,fragment). Engine-agnostic; answers "what's actually in the cache folder". -
Page cache explorer — because the disk (Enhanced) page cache mirrors your URL structure on disk, it's browsable as a folder tree. Each folder shows a recursive rollup — how many distinct pages are cached beneath it, their total size, and a live / expired / stale-copy breakdown — so a folder like
productstells you how many of that post type are currently cached. Navigation is lazy (one directory level per request) and bounded by a shared file budget, so it scales to very large caches. Individual pages show reconstructed URLs with variant badges (ssl / gzip / mobile). (Memory engines hash their keys, so this is disk-only.)-
Stale awareness: a raw file count includes entries W3TC has invalidated but not yet garbage-collected. The explorer breaks these out:
- expired — a live page older than
pgcache.lifetime(still on disk, pending GC); - orphaned — a directory whose live primary is gone, leaving only
*_oldregeneration copies (dead weight from a purge/expiry); _oldon disk — total bytes those regeneration copies occupy.
Each level shows a summary line — pages / live / expired / orphaned / size /
_oldbytes /expires after(the actualpgcache.lifetime) — so you can see at a glance how much of the cache is genuinely live versus debris, and why "live" is (or isn't) a rolling window. - expired — a live page older than
-
Clean up
_oldfiles: when a level holds_oldregeneration copies, a button removes them (scoped to the current path — at the root it clears the whole page cache). It only ever deletes files ending in_old— live primaries, gzip variants and.htaccessare never touched — and prunes directories those deletions leave empty.manage_optionsonly, with a confirm; the operation is time-bounded and reports files removed + bytes freed. Disable entirely with thew3tcci_allow_cleanupfilter. -
Engine requirement: the explorer needs Disk: Enhanced specifically. On Disk: Basic (hashed filenames) or Redis/Memcached (hashed keys) URLs can't be reconstructed, so it shows a clear explanation instead — the rest of the dashboard still works on any engine.
-
-
Memory backends — live Redis / Memcached / APCu stats (memory used, hit rate, gets/hits) for whichever backend W3TC is configured to use.
-
Recent flushes — a capped feed of cache flush/purge events captured from W3TC's public flush hooks.
-
Purge log — recent per-module purge entries (who/what triggered each purge, with a backtrace), when W3TC's purge logging is enabled.
-
Enabling purge logging on the free version: the Purge Logs checkboxes under Performance → General Settings → Debug are Pro-gated in the admin UI, but the logging itself lives in the free engine — the config flags just can't be ticked from the screen. Set them via WP-CLI and the free version logs fine:
wp w3-total-cache option set pgcache.debug_purge true --type=boolean wp w3-total-cache option set dbcache.debug_purge true --type=boolean wp w3-total-cache option set objectcache.debug_purge true --type=booleanLogs land in
wp-content/cache/log/<key>/{pagecache,dbcache,objectcache}-purge.logand this card surfaces the newest entries with backtraces. Caveat: saving W3TC settings in wp-admin can silently reset these flags (the Pro-gated checkboxes submit as unchecked), so re-check after any settings save. Turn logging off again the same way (… false --type=boolean) once you've caught your culprit — each purge writes a backtrace to disk.
-
Cache priming (opt-in, 0.3.0+)
After any purge, every un-cached page costs its first visitor a full PHP render — and a bot walking the long tail can turn a cold cache into a load spike. The primer converges the origin Disk: Enhanced page cache back to warm, and keeps it there:
- The filesystem is the state. Each run stat-checks the expected cache file for every sitemap URL (sub-second even at tens of thousands of URLs) — there is no state column to drift. Missing file = cold = crawl it.
- Nearly-expired pages are refreshed proactively (unlink + immediately re-request, one page at a time) so W3TC's garbage collector never leaves a page cold for a whole cron interval. True gaps are always filled first.
- Load-aware: backs off when the 1-minute load average crosses a ceiling (default 0.75 × cores), with a per-request delay and batch cap. A transport circuit breaker aborts the run if prime requests stop producing cache files.
- Two request modes:
public(plain request to the site URL — right for most sites) andloopback(curl--resolveto the origin itself with real SNI/Host — required where Cloudflare APO or a cache-everything rule serves HTML from the edge, since an edge HIT would silently skip the origin). The end-to-end self-test — request a page, then verify its cache file appeared — proves the transport, vhost routing and URL→path mapping in one click, and gates every run. - Sitemap-driven inventory (Yoast / core sitemap indexes, per-locale child sitemaps included), re-ingested periodically with a shrink guard so a partial sitemap response can't gut the inventory.
Run it from a real system cron via WP-CLI (preferred — no FPM workers consumed):
* * * * * cd /path/to/site && wp cache-insights prime >/dev/null 2>&1
Every-minute is fine (an idle tick is a sub-second scan); sparser schedules work too. Hosts without CLI/cron access can switch the scheduler setting to a WP-Cron fallback (small batches, 20s time budget).
wp cache-insights status [--scan] # inventory, live warm/cold counts, run history
wp cache-insights sitemap # re-ingest the sitemap, per-child breakdown
wp cache-insights selftest [<url>] # strict end-to-end pipeline proof
wp cache-insights prime [--batch=<n>] [--time-budget=<s>] [--force] [--dry-run]
Notes: disable W3TC's built-in "cache preload" when priming is on (it re-requests warm pages blindly and doubles background volume). Priming requires Disk: Enhanced; the primer only ever requests your own site and tracks the primary variant a real cold visitor would trigger.
How it stays light
- Cheap "overview" data (engine per module) is read from config and is effectively free.
- Expensive work (walking the disk cache) runs only when you open the dashboard, is bounded by a wall-clock timeout, and is throttled behind a short-lived transient so refreshes don't re-scan the tree.
- The flush feed only writes to the database when a flush actually happens, buffers events in memory during a request, and writes once on shutdown to a non-autoloaded option.
Which W3TC internals it uses
Only a tiny part of W3TC is a stable public API (w3tc_config(), w3tc_flush_*(), documented w3tc_* hooks). Everything else this plugin reads is internal and therefore guarded with class_exists() / method_exists() and degrades gracefully if it changes:
| Data | Source |
|---|---|
| Active engine per module | w3tc_config()->get_string('{module}.engine') |
| Disk cache dir | \W3TC\Util_Environment::cache_dir() / W3TC_CACHE_* constants |
| Live Redis/Memcached/APCu stats | \W3TC\UsageStatistics_Sources::w3tc_usage_statistics_metric_values() (runs the w3tc_usage_statistics_sources filter) |
| Engine display names | \W3TC\Cache::engine_name() |
| Purge log | \W3TC\Util_DebugPurgeLog_Reader::read() |
| Flush feed | public actions w3tc_flush_all, w3tc_flush_post, w3tc_flush_posts, w3tc_flush_url, w3tc_flush_group, w3tc_flush_dbcache, w3tc_flush_objectcache, w3tc_flush_minify |
It deliberately avoids W3TC's history/hit-rate counters (w3tc_stats_history), which require W3TC Pro plus per-module debug logging.
Filters
| Filter | Default | Purpose |
|---|---|---|
w3tcci_snapshot_ttl |
300 |
Seconds to cache a computed snapshot. |
w3tcci_walk_timeout |
10 |
Max seconds spent walking a disk cache directory. |
w3tcci_pages_file_cap |
5000 |
Max cache files scanned when building the flat cached-pages list. |
w3tcci_tree_file_budget |
20000 |
Max files scanned per explorer level (shared across that level's folder rollups). |
w3tcci_tree_max_folders |
500 |
Max folders returned per explorer level (largest-first). |
w3tcci_allow_cleanup |
true |
Master switch for the "Clean up _old files" action. |
w3tcci_cleanup_timeout |
20 |
Max seconds a single cleanup pass runs before returning truncated. |
w3tcci_activity_log_enabled |
true |
Turn the flush feed on/off. |
REST API
All routes require manage_options. Every route is read-only except POST /clean-old, which deletes _old files.
GET /wp-json/w3tc-cache-insights/v1/overviewGET /wp-json/w3tc-cache-insights/v1/snapshot?force=trueGET /wp-json/w3tc-cache-insights/v1/cache-dir(whole cache folder, per sub-dir)GET /wp-json/w3tc-cache-insights/v1/tree?path=products(explorer; one level)GET /wp-json/w3tc-cache-insights/v1/pages?limit=200(flat list alternative)POST /wp-json/w3tc-cache-insights/v1/clean-old(delete_oldfiles underpath)GET /wp-json/w3tc-cache-insights/v1/activityGET /wp-json/w3tc-cache-insights/v1/purge-logGET /wp-json/w3tc-cache-insights/v1/prime/status(primer settings, counts, run history)POST /wp-json/w3tc-cache-insights/v1/prime/settings(update primer settings)POST /wp-json/w3tc-cache-insights/v1/prime/test(strict end-to-end self-test)
Requirements
- WordPress 5.6+
- PHP 7.2+
- W3 Total Cache
License
GPL-2.0-or-later.
Releases
5 releases. Each count is every asset in that release; expand a row for the breakdown.