Cache Autopilot – Documentation
Cache Warmup
Updated:
Overview
Cache Warmup is the warmup (cache preload) execution engine. It receives invalidated URLs from Cache Invalidator, responds to cache-wide purge events, and rebuilds cache by issuing HTTP GET requests in background batches. The first batch is prompted immediately when possible; WP-Cron keeps longer runs moving safely.
Key capabilities:
- Targeted warmup for specific URLs after content changes
- Full warmup from sitemaps after cache-wide purge events
- Adaptive auto-pacing based on server response telemetry
- Priority ordering (priority pages, post type order, default-language-first)
- Sitemap membership filtering
- Deduplicated queue with per-cron pacing and execution safeguards
- Run history logging with retention management
- REST API for settings and diagnostics
How Cache Warmup Operates
- URLs received — from Cache Invalidator, cache purge events, or manual triggers
- Queue built — URLs are deduplicated, prioritized, checked for frontend eligibility, and matched against sitemaps where applicable
- Batches started — a non-blocking kick starts work promptly, while WP-Cron provides reliable continuation and fallback
- Pacing adapts — batch size adjusts based on server response telemetry
- Run completes — results logged, queue cleared, ready for next trigger
See: Cache Warmup → Diagnostics if warmup does not run as expected.
Configuration Concepts
Cache Warmup is configured through the plugin’s admin settings UI. The key concepts are summarized here; for exact field definitions, see the Settings Reference below.
Sitemaps and URL Resolution
Sitemaps serve two purposes:
- Full warmup URL source
When a full warmup is triggered, URLs are resolved from configured sitemaps. - Membership filtering
Most targeted warmup URLs are checked against sitemap membership. Deterministic public URLs received directly from Cache Invalidator can use its trusted result instead.
The sitemap resolver supports:
- Sitemap index files with recursive child sitemap discovery
- Standard
urlsetsitemaps - URL canonicalization and deduplication
Full warmup discovery has no fixed product-level URL limit. Per-cron pacing controls how much work is processed at once; larger sitemap sets simply continue across additional background batches.
See: Cache Warmup → Sitemap Membership Filtering for filtering behavior details.
Priority Pages and Post Type Ordering
URLs are processed in priority order:
- Front page
The front page URL is added automatically and warmed first. With multilingual fanout enabled, its available language versions are included in this tier. - Priority pages
Specific page IDs configured as high-priority. These are warmed immediately after the front page. - Post type groups
URLs grouped by post type, in the configured order (default: pages first). - Other URLs
Taxonomy archives, unclassified URLs, and everything else.
Within each tier, if a multilingual plugin is active, URLs in the default language are warmed before other language variants. Pending invalidation URLs already awaiting processing remain ahead of newly planned full-warmup URLs.
Manual Exclusions
URLs listed in the manual exclusions field are removed from the warmup queue before processing begins. This applies to both targeted and full warmup runs. URLs are canonicalized before comparison.
Pacing
Two pacing modes are available.
- Auto mode uses server response telemetry to dynamically adjust batch size and timing.
- Manual mode uses fixed values for pages per batch, throttle delay, and max batch seconds. Auto mode is recommended for most sites.
See: Cache Warmup → Batch Execution and Pacing for operational details.
Logging
Run history is stored in a custom database table with configurable retention. Old entries are cleaned up daily via WP-Cron.
See: Cache Warmup → Logging and Run History for details.
Warmup Triggers
Targeted Warmup
Targeted warmup processes specific URLs after content changes. Triggers include:
- Cache Invalidator emission
URLs received via theekesto_ci_invalidation_urlsaction. This is the primary targeted warmup path. - Post save
When a public post is saved and qualifies as a frontend target, its canonical permalink is warmed. Revisions, autosaves, and editor-only structural entities are skipped.
Targeted URLs from general sources are checked against sitemap membership before enqueueing. Trusted deterministic targets from Cache Invalidator skip only this membership check; they are still canonicalized and checked as safe frontend URLs.
Editor-only entities (for example block templates, template parts, reusable components, or builder presentation templates) are excluded even if they expose queryable URLs.
Full Warmup
Full warmup builds a complete plan from the configured sitemaps, then places the front page and selected priority pages at the front of that plan. Triggers include:
- Cache adapter purge-all
When the active cache plugin flushes all cache (e.g., via its admin UI). Debounced to shutdown to coalesce multiple hooks. - Core/plugin/theme updates
Afterupgrader_process_completefires, a deferred maintenance warmup is scheduled. - Plugin activation/deactivation
Treated as maintenance events. - Theme switch
Treated as a maintenance event.
Full warmup uses the full run restart policy (Policy B): if a full run is already active and a new full trigger fires, the current run is finalized as restarted and a new run begins with a fresh URL list.
Upgrade window suppression: After maintenance triggers, purge-all hooks are suppressed for 30 seconds to prevent redundant full warmups from update-triggered cache flushes.
Maintenance Warmup
Maintenance events (updates, plugin activation, theme switches) defer warmup by 15 seconds via a dedicated WP-Cron hook. This separates warmup from the updater process, which may block.
Manual Warmup
The Trigger full cache refresh action in the Warmup settings purges the cache first, then rebuilds the planned URLs in background batches.
Trigger full cache refresh sends a non-blocking kick so the first batch can begin promptly after the purge request has safely completed. WP-Cron remains the fallback and continues later batches, so the exact start time can still depend on the server.
Single URL Warmup
Individual URL warmup is triggered by save_post for eligible public content. The single URL is either:
- Merged into an active run (at the current processing position for priority treatment), or
- Started as a new targeted warmup run if no run is active.
Operational summary: Full runs process all sitemap URLs. Targeted runs process specific invalidated URLs. New URLs merge into active runs without duplication.
Queue System
A persistent queue stored in WordPress options tracks the state of each warmup run.
Queue State and Modes
The queue operates in two modes:
- Full mode
Processing all URLs from sitemaps, including large sitemap sets. - Single mode
Processing one or more targeted URLs. Typically a small set.
Queue state includes: active flag, unique run ID, mode, trigger source, URL list, current processing position, warmed/failed counters, and last activity timestamp.
Only URLs that pass frontend eligibility checks enter the queue. Editor-only entities and structural builder content are filtered before enqueueing to prevent warming non-frontend URLs.
URL Merging and Prioritization
When an eligible targeted URL arrives during an active run:
- During a full run: The URL is inserted at the current processing position. If the URL already exists later in the queue, it is moved forward. This provides priority treatment without duplicating work.
- During a single run: The URL is merged with deduplication.
URLs are deduplicated at enqueue time. A full warmup keeps the complete resolved target list; per-cron limits control only how many URLs are processed during each execution.
If work remains, the queue keeps its position and continues in later WP-Cron batches. Newly invalidated URLs can still be moved forward or merged into an active run without duplication.
Run Restart Behavior
Full run restart policy (Policy B):
- A new full trigger while a full run is active finalizes the current run as restarted and begins a new run.
- A new full trigger while a single run is active also finalizes and restarts.
- If the new full trigger produces an identical URL list to the active run, the restart is skipped (deduplication).
Stale Run Recovery
If a run shows no activity for longer than the stale run threshold (default: 15 minutes), it is marked as “failed” and the queue is reset. This prevents stuck runs from blocking future warmups.
Stale recovery is checked before new enqueue operations.
Operational summary: The queue ensures ordered, deduplicated execution. New URLs merge into active runs automatically. Stale runs are recovered to prevent blocking.
Batch Execution and Pacing
Each execution processes one batch of URLs. If work remains after a batch completes, the next batch is scheduled through WP-Cron.
Adaptive Auto-Pacing
When pacing mode is set to auto, Cache Warmup adjusts each cron batch from measured server performance.
- Bootstrap phase — starts conservatively while response-time data is collected.
- Telemetry phase — uses the p90 response time from a rolling window of up to 200 recent warmup requests to calculate a safe effective batch size.
The available execution window is derived from the server’s PHP execution limit with safety headroom. Internal execution safeguards still apply, but they limit one cron run — not the total size of the warmup.
Automatic is recommended for most sites. Use Manual only when you need fixed request-rate or execution limits.
Manual Pacing
When pacing mode is set to manual, the configured pages per batch, throttle seconds, and max batch seconds values are used directly.
WP-Cron Timing
New runs are prompted immediately when possible, while scheduled WP-Cron events provide continuation and a reliable fallback:
- First batch: prompted immediately through a non-blocking request when possible, with a scheduled event retained as a safety net.
- Subsequent batches: scheduled 60 seconds after the previous batch completes.
Cache Warmup uses spawn_cron() or a private non-blocking loopback request to prompt execution without making the admin or content request wait for the warmup.
Operational summary: Auto pacing adapts to your server automatically. Manual pacing gives direct control. Immediate kicks make new runs feel responsive, while WP-Cron provides dependable continuation and recovery.
See: Cache Warmup → Batch Execution and Pacing → WP-Cron Timing for more details.
See: Troubleshooting → WP-Cron Not Running if batches are not executing on schedule.
Sitemap Membership Filtering
Targeted warmup URLs are always validated for frontend eligibility. URLs from general or untrusted sources are also checked against cached sitemap membership before warmup.
URLs not present in any configured sitemap are typically filtered out. Deterministic URLs supplied directly by Cache Invalidator may bypass the membership check because their public target has already been resolved; they still pass URL canonicalization and frontend safety checks.
URLs representing editor infrastructure (for example templates, reusable components, or builder presentation documents) are excluded before sitemap checks.
Membership behavior
- Sitemap membership is prepared and refreshed automatically
- Targeted membership checks use the persisted membership data and do not fetch the sitemap live
- Relevant content and sitemap-configuration changes schedule a background refresh
- A successful full warmup also refreshes membership from the latest sitemap data
Matching behavior
- URLs are canonicalized using WordPress permalink rules
- Trailing-slash differences are normalized during lookup
- HTTP and HTTPS variants of the same host and port can match
- Different hosts and custom ports remain distinct
This allows targeted warmups to validate URLs quickly without resolving the complete sitemap for every content change.
If an expected URL is skipped, first verify that it appears in a configured sitemap.
See: Troubleshooting → URLs Not Warming if expected URLs are being filtered out.
Settings Reference
Settings are organized by tab and panel, matching the plugin’s admin UI.
Warmup Tab
General
- Automatic warmup — Automatically rebuilds cache after content changes, targeted invalidation, and cache purges. Work begins promptly when possible and continues in safe background batches.
- Trigger full cache refresh — Purges the entire cache and builds a complete warmup plan from the configured sitemaps. The first batch is prompted promptly after the purge request finishes safely; WP-Cron continues longer runs.
Sitemaps
- Sitemap URL(s) — One URL per line. Sitemap indexes are supported. Used for full warmup URL resolution and sitemap membership filtering of targeted URLs.
- Manual URL Exclusions — URLs to skip during warmup (one per line), even if they appear in your sitemap.
Priorities Tab
Warmup Priorities
Controls the order in which URLs are warmed during a full warmup. Post types are detected from your sitemap — drag to reorder.
- Front page (automatic)
- Selected priority pages
- Post types in configured order
- Remaining URLs, such as archives and unclassified targets
Refresh sitemap data re-reads the configured sitemap and its child sitemaps, then updates the detected post types, counts, and total number of unique usable URLs.
Operational sitemap membership refreshes automatically after relevant site changes, so manual refresh is mainly useful after adding or removing post types or changing sitemap configuration.
With multilingual support active, default-language URLs are warmed first within each priority group.
Priority Pages
The front page is added automatically, warmed before selected priority pages, and omitted from the list. Select additional pages to warm immediately after it and before all post type groups. On multilingual sites, choose the default-language page once; Cache Warmup adds its available translations automatically when multilingual fanout is enabled.
Use Shift + F to focus the fuzzy search. If a newly published or translated page is missing, refresh the list to load the latest choices.
Log Tab
Recent runs
The button Run Next Warmup Batch executes the next queued warmup batch immediately.
Useful if WP-Cron is delayed or disabled.
The run history table shows recent warmup runs:
| Column | Description |
|---|---|
| Started | Run start time in server timezone |
| Duration | Total run time |
| Trigger | What caused the run, shown as a readable label |
| Mode | Targeted: specific URLsTargeted / Updated: more URLs were added to an active targeted runFull: sitemap-wide warmup |
| Status | preparing, pending, running, finished, failed, restarted, stopped, or stale |
| Total / Warmed / Not warmed | URL counts: processed, successfully warmed, and not warmed |
| View Icon | Expands the per-URL results for a run |
Expanded results distinguish successful Warmed URLs from Not found pages and genuine Failed requests. Paginated archive pages that do not exist are reported as Not found, not as failures.
For failed URLs, the details distinguish the browser-profile attempt from the final standard request. This makes it clear whether fallback was used and which HTTP status ultimately caused the failure.
Log settings
Log retention — Days to keep warmup run logs (1–365). Default: 30.
Diagnostics Tab
Warmup Transport
Shows the active HTTP request strategy and performance across up to 200 recent warmup requests. The browser profile advertises Brotli, GZIP, and Deflate; the server selects the response encoding. Cache Warmup uses the WordPress HTTP API for both steps:
- A browser-profile request that advertises the compression formats supported by modern browsers
- A standard WordPress HTTP request if the browser-profile request is unavailable or does not return a successful response
Click Check transport status (or Refresh transport status after the first check) to update the capability check and recent performance summary. A fallback is not automatically a failed warmup: the standard request can still complete successfully.
| Field | Description |
|---|---|
| Strategy | The request path currently in use: browser-profile request with standard fallback, or standard WordPress HTTP request only |
| Browser-profile request | Whether this server can make the browser-profile request through the WordPress HTTP API. Availability does not confirm that Brotli was delivered. |
| Unavailable reason | Shown only when the browser-profile request cannot run; explains the server limitation in plain language |
| Recent warmup requests | Number of requests currently represented in the rolling performance window, up to 200 |
| Standard fallback rate | Percentage of recent requests that needed the standard fallback |
| p90 total request (ms) | End-to-end response time, including both attempts when fallback was needed |
| p90 browser-profile request (ms) | Response time for the browser-profile attempt, regardless of the response encoding selected by the server |
| p90 standard fallback (ms) | Response time for the standard fallback attempt only |
| Last standard fallback | Shown after a fallback is observed; includes when it happened and a readable reason |
| Checked at | When the transport status was last refreshed |
p90 means 90% of matching requests completed within this time. Total and browser-profile p90 values need at least 10 matching requests; standard fallback p90 needs at least 10 fallbacks. Until enough data exists, the UI shows an em dash (—) and a short explanation. The end-to-end timing also informs auto-pacing.
Connectivity
Tests whether WordPress can reach this site using its built-in HTTP API. Both warmup request profiles use that API, so this check helps diagnose firewall, DNS, or hosting restrictions that block outbound self-requests.
Click Run self-check to test. This is a manual diagnostic action — not required for normal operation.
| Field | Description |
|---|---|
| Result | OK or FAIL |
| HTTP status | Response status code from the self-request |
| Message | Response summary or error description |
| Response time (ms) | Round-trip time for the self-request |
| Target URL | The URL that was tested (site front page URL) |
| Checked at | When the self-check was last run |
A FAIL result typically means the server cannot make HTTP requests to itself. Common causes: firewall rules, DNS resolution issues, or hosting restrictions on loopback connections. Contact your host if this persists.
PHP limits
Shows your server’s max_execution_time. This determines how long each warmup batch can run. Auto-pacing uses ~80% of this limit as safe headroom. At least 30 seconds is recommended.
WP-Cron
WP-Cron handles scheduled continuation and fallback batches. Click Run Diagnostics to check your setup:
| Field | Description |
|---|---|
| DISABLE_WP_CRON | Whether built-in cron triggering is disabled |
| ALTERNATE_WP_CRON | Whether WordPress uses the alternate cron method |
| Last warmup queue activity | Most recent timestamp when the warmup queue was updated (enqueue, batch processing, or state change). Shows whether the warmup system is active. |
If DISABLE_WP_CRON is true, set up a server cron to call wp-cron.php every 1–5 minutes. This is especially important on low-traffic sites where visitor-triggered cron may not fire often enough.
See: Cache Warmup → Batch Execution and Pacing → WP-Cron Timing for more details.
Advanced Tab
Warmup Engine
Controls how many URLs are processed per warmup batch. Each batch stops when either the URL limit or time limit is reached.
- Tuning Mode — Automatic (recommended) adjusts batch size from server response telemetry. Starts conservatively, then adapts after 30+ samples. Manual uses fixed values you set.
- Max URLs per cron run (manual) — Maximum URLs one cron execution may process. This does not limit the total number of URLs in a warmup.
- Max batch duration (manual) — Maximum time one cron execution may spend processing URLs. Keep below your server’s
max_execution_time. - Delay between requests (manual) — Seconds between warmup requests. Use
0for no added delay. - Reset Tuning Data — Clears collected response-time samples so Automatic tuning starts fresh.
User Agent
User-Agent — Custom string appended to warmup request headers. Useful for filtering warmup traffic in analytics or server logs. Leave empty for the default.
Queue Behavior
Defaults work for most setups. Override only if your hosting requires it.
- Stale run threshold — Minutes of inactivity before a run is marked stale (5–1440). Protects against stuck runs. Default: 15.
Cache Adapters
The active cache adapter is detected for two purposes:
- Purge hook registration
Listening for cache-wide purge events to trigger full warmups. - Availability check
Warmup only runs when a cache adapter is detected.
See: How It Works → Cache Adapters for the supported adapter list.
See: Developer Reference → Cache Adapter Compatibility for adapter-specific notes and extension points.
Diagnostics
The Diagnostics tab helps verify that warmup can run correctly on your server. Check it when warmup is not progressing as expected, or after hosting changes.
Three panels cover the key areas: transport health and connectivity, PHP execution limits, and WP-Cron configuration.
See: Cache Warmup → Settings Reference → Diagnostics Tab in the Settings Reference for field descriptions.
Logging and Run History
A custom database table stores run history for all warmup activity.
Each run record includes:
- Unique run ID, trigger source, mode, status
- Start, update, and finish timestamps (UTC)
- URL counts (total, warmed, failed)
- Per-URL event details (status codes, response times, errors)
Run statuses:
| Status | Meaning |
|---|---|
| running | Batch execution in progress |
| finished | All URLs processed |
| failed | Stale run recovery or fatal error |
| restarted | Superseded by a new full warmup trigger |
| stopped | Manually stopped |
| stale | Marked stale by log cleanup |
Run history is cleaned up daily. Entries older than the retention period are deleted. Runs still marked “running” after 6 hours are marked “stale.”
Operational Best Practices
- Disable your cache plugin’s own preload when Cache Warmup handles preloading, so both systems do not rebuild the same pages.
- Use a server-side cron job on low-traffic or staging sites so continuation batches run reliably.
- Keep Automatic pacing enabled unless you have a specific reason to use fixed limits.
- Pause warmup during continuous edits that trigger full cache flushes, large imports, or migrations to avoid unnecessary rebuilds.
- Use priority pages for important landing pages that should be rebuilt first after a full purge.
Developer Extensions
Cache Warmup integrates with Cache Invalidator via the hook bridge. For extension points and customization filters, see the Developer Reference.
See: Developer Reference → Filters for available hooks and filters.
See: How It Works → The Hook Bridge for how the two engines communicate.