Repository navigation
Tools
GT Performance > Tools holds the operational views: runtime status, Explain this page, the health report, cache warming, verified purge receipts, settings history with export and import, and the background queue. The everyday buttons (install drop-ins, purge, sync Cloudflare) are on the Dashboard under Operations.
Everything here is also available from WP-CLI. See WP-CLI.
A quick read of the four things caching depends on:
| Row | Values |
|---|---|
| Page-cache drop-in | Installed by GT Performance, Not installed, Owned by another plugin |
| WP_CACHE | Enabled, Disabled |
| Redis drop-in | Installed by GT Performance, Not installed, Owned by another plugin |
| Cache directory | Writable, Not writable |
GT Performance never overwrites a drop-in owned by another plugin. See Troubleshooting. In optimize-only mode the page-cache drop-in is not used, so Not installed is expected there.
Why one URL is or is not cached, and what the origin and Cloudflare hold for it. Enter a URL on the home host (the home page is filled in) and press Explain. It is checked as a signed-out visitor; nothing is fetched or purged.
| Row | Shows |
|---|---|
| URL | The URL explained |
| Decision |
Cacheable, or Bypassed with the machine-readable reason, such as path:/cart/ or page-option
|
| Origin copy | Stored and fresh, Stored, stale (served while it is rebuilt), Stored, expired (the next visit rebuilds it), or Not stored |
| Stored, Fresh until | When the stored copy was written and until when it is fresh |
| Size | The stored copy's size |
| Cache key | The first 12 characters of the key hash, the same value as X-GT-Cache-Key
|
| Cloudflare | Shown when Cloudflare is connected: whether the managed rule agrees with the origin, or the disagreement to fix |
Below the report, Open this page with every optimization off opens the URL in per-request safe mode, for an administrator only. The admin bar's Explain this page item opens this panel with the current page's URL filled in. The report is the same one wp gt-performance cache explain prints; see Diagnostics.
One bounded report, shared by four places:
- Tools > Health: a table of Check, Status (Pass, Review, Fail or Info), Detail and Observed.
- WordPress Site Health, as the GT Performance health test. See Diagnostics.
- WP-CLI, which exits with status 1 when any check fails:
wp gt-performance health # table: label, status, value, source wp gt-performance health --format=json # the redacted support export
-
Download support report on the Health panel, which saves the same redacted JSON as
gt-performance-health-<date>-<time>.json.
Every check reads saved state or a cheap local probe. The report requests no pages, walks no cache directory and contacts no edge provider. Each check says whether its value is live or saved, and when it was observed, so a saved result is never mistaken for a live one. It does not estimate a hit rate: cache and edge hits never run WordPress, so the plugin cannot count them.
| Check | Review or Fail when |
|---|---|
| Background queue | Any job has failed, or the oldest due job has waited more than 15 minutes. Shows pending, running and failed counts and whether optional work is paused. While a schema upgrade is pending it says new jobs wait for an admin screen or WP-CLI to finish it |
| Queue runner | No scheduled queue run recorded yet, or the last one was more than 15 minutes ago |
| WP-Cron |
DISABLE_WP_CRON is set and scheduled events are more than 15 minutes overdue |
| Cache storage | The cache directory is not writable (Fail) |
| Page-cache drop-in | The drop-in is missing or WP_CACHE is off (Review), or another plugin owns the drop-in (Fail). Info when origin page cache is disabled, or in optimize-only mode, where it says the host's page cache stores pages and the drop-in is not used |
| Object-cache drop-in | Shown only when Redis is enabled; Review when the drop-in is not GT Performance's |
| Edge ownership | Shown only when xCloud and direct Cloudflare both claim the edge |
| Runtime configuration | The last settings save could not be published to the runtime config (Fail) |
| Purge verification | The latest of the last 5 verification receipts was not verified. Info when none has been run |
| Unused CSS reports | Shown only when unused CSS is on; Review when any of the 50 most recent reports failed |
| Language and currency plugins | Shown only while one of the language or currency plugins GT Performance detects is active, always as Review. It names them and points to Integrations for what to set |
| Cache warming | The latest run is partial or capacity limited, has failed URLs, or has made no progress for 30 minutes. Info when no run has been recorded |
The overall result is the worst check. Check names and messages are translatable, so they follow the site's language when a translation is installed; the plugin ships its template as languages/gt-performance.pot. The support export contains schema_version, observed_at, the plugin, WordPress, PHP and database schema versions, and the checks. Before it leaves wp-admin, every string has the WordPress and content directory paths replaced with [abspath] and [content], URLs cut down to scheme, host and path, and token- or password-like values redacted. The WP-Cron check leaves out the server runner command, which carries an absolute path, and points to wp gt-performance doctor for it.
Source: HealthReport.
The Cache warming panel shows the latest warm run: its state (Discovering, Warming, Complete, Partial, Capacity limited or Superseded), how many pages the origin actually stored (Origin ready), how many only the edge answered (Edge only), how many are waiting or failed, and how many sitemaps were read. Start warm run queues a new run. In optimize-only mode it queues nothing and says why. See Cache Warming.
The 10 most recent purge verifications: URL, status (verified, warning or failed), what the edge reported, and when. Run one from a front-end page with the admin bar's Purge and verify this URL, or with wp gt-performance cache verify. See Diagnostics.
Every settings save keeps the values it replaced, so a change can be reviewed and undone.
- What is recorded. The non-secret projection of the settings, before the save. Tokens, API keys, passwords, usernames and account emails never enter it.
- When. On every save that changes a non-secret value, from any source. Saves that change only credentials record nothing.
-
Limits. The last 20 saves, none older than 90 days, 512 KB in total (the oldest are dropped first). Stored in the non-autoloaded
gt_performance_settings_historyoption.
The Settings history panel lists each revision:
| Column | Shows |
|---|---|
| Replaced | How long ago the save happened |
| By | Where the save came from (admin, cli, rest, system, or restore, import, proposal) and the user ID |
| Differences from now | "Same as current", or the number of settings that differ, expanding to each setting.path: old → new and a Restore these values button |
Restore these values applies that revision's values on top of the current settings, through an ordinary settings save: values are sanitized again, the runtime config is published, the cache generation advances when a restored value reaches cached pages, so they rebuild (a restore from wp-admin also purges them; see Page Cache), and the values being replaced become a new history entry. The restore is refused with "Settings changed after this preview. Review the current settings and try again." if anyone saved in the meantime.
A restore never touches:
- credentials of any kind (they are not in history to begin with),
- the cache generation counter,
- Agent access and the AI adviser settings,
- Redis settings,
- xCloud settings,
- Cloudflare's enabled state, authentication mode, domain and zone ID.
Restoring changes local settings only. When Cloudflare is connected and the restore changes page cache or Cloudflare values, the notice says to run Connect/sync Cloudflare; the managed rule is not changed until you do.
wp gt-performance config history # revision IDs, time, source, user, differences
wp gt-performance config diff 3f2a # what restoring would change (ID or unique prefix)
wp gt-performance config restore 3f2a --dry-run # same preview
wp gt-performance config restore 3f2a --expected-hash=<hash>--expected-hash refuses the restore unless the current settings still have the hash printed by history or diff.
Every settings write takes one lock: the settings form, WP-CLI, Cloudflare and xCloud connection flows, restore, import and proposal approval. A save that cannot get the lock within 10 seconds is refused with "Another settings change is in progress", and the form keeps the saved settings rather than overwriting them. Connection flows that make a slow remote call save only the keys they changed, on top of the settings read under the lock, so they cannot undo another administrator's save.
Sources: RevisionRepository, SettingsLock.
Export settings on the Settings history panel downloads gt-performance-settings-<date>-<time>.json:
{
"format": "gt-performance-settings",
"schema_version": 1,
"plugin_version": "1.2.0",
"exported_at": "2026-09-27T10:00:00+00:00",
"settings_hash": "…",
"settings": {
"debug": false,
"cache": { "enabled": true, "fresh_ttl": 3600, "…": "…" },
"…": "…"
}
}Included: Diagnostic logging (debug) and the cache, css, javascript, media, fonts, database, bloat, commerce, integrations and speculation sections in full, the CDN's enabled, url and file_types, and the Cloudflare edge cache lifetime (cloudflare.edge_ttl).
Excluded:
- every credential: Cloudflare API token, Global API Key and account email, the xCloud API token, Redis username and password;
- the cache generation counter;
-
Agent access (
agents) and the AI adviser (advisor); - all Redis settings and all xCloud settings;
- Cloudflare's enabled state, authentication mode, domain and zone ID;
- Remove all data when the plugin is deleted;
- any key whose name looks like a credential (it contains
token,secret,password,passwd,username,email,api_key,privateorcredential). The quick togglebloat.disable_password_strength_meteris a reviewed exception and is exported; any new credential-like key is still left out.
The CDN URL is included, so review it before importing a file on another site.
To import, choose the file under Import an exported settings file and press Preview import (files up to 256 KB). The whole file is rejected if it is not a GT Performance export, uses an unsupported schema version, or contains any setting this site does not accept, including the excluded ones above. The preview lists every setting: current → new change and is kept for 15 minutes. Apply imported settings then applies it through an ordinary settings save, and is refused if settings changed after the preview. Protected settings are never changed by an import, and the Cloudflare sync notice applies as it does for a restore.
wp gt-performance config export --file=settings.json # prints to stdout without --file
wp gt-performance config diff settings.json
wp gt-performance config import settings.json --dry-run
wp gt-performance config import settings.json --expected-hash=<hash>Source: ConfigurationService.
Work that should not happen in a visitor's request goes into the {prefix}gtperf_jobs table: page preloads and stale revalidation, URL purges, warm-run discovery and dispatch, unused CSS builds and batch regeneration, image variants, Google Fonts localization, database cleanup, and assistant operations.
How it runs
- WP-Cron runs the queue every minute. Each run processes up to 25 jobs within a 20-second budget, then queues revalidation for a few stale pages and deletes finished, failed and cancelled jobs older than three days.
- One runner per site. A second runner started at the same time exits without doing anything.
- Asking for the same work twice (same job type and target) while it is waiting or running returns the existing job instead of adding another.
Exclusive claiming
A job is claimed with a conditional update, so two workers can never take the same job. Each claim gets a token and a 10-minute lease that long jobs renew. A worker that lost its lease, or whose job was cancelled, cannot mark the job complete or publish its generated files and CSS reports.
Failures and crashed jobs
Attempts are counted when a job is claimed. A job that throws is retried after 30 seconds, then after 60; after its third attempt it is marked failed with its last error (redacted). A job whose worker dies mid-run is reclaimed once its lease expires, and after three claims it is marked failed with "Worker lease expired." instead of retrying forever.
Starvation protection
Jobs run by priority, and waiting jobs age toward the front: after 30 minutes, 2 hours and 6 hours of waiting they are treated as progressively more urgent. Cache purges always run first, so a steady stream of CSS builds cannot hold a warm run back indefinitely.
Controls
The Background queue panel shows Pending, Running and Failed counts, the State (Running or Paused), and the 20 newest jobs with their ID, type, last error, status, attempts and last update.
| Action | Tools tab | WP-CLI |
|---|---|---|
| Pause optional work | Pause optional work | wp gt-performance queue pause |
| Resume | Resume queue | wp gt-performance queue resume |
| Retry a failed job | Retry on the row | wp gt-performance queue retry --id=<id> |
| Cancel a pending or running job | Cancel on the row | wp gt-performance queue cancel --id=<id> |
| Counts | Panel stats | wp gt-performance queue status |
| List jobs | Panel table | wp gt-performance queue list [--status=<status>] [--limit=<n>] |
| Run jobs now |
wp gt-performance queue run [--limit=<n>] (or just wp gt-performance queue) |
- Pause holds everything except cache invalidation: URL purges keep running. Warming, preloads, CSS builds, image variants, font localization, database cleanup and assistant operations wait until you resume.
- Retry works on failed jobs only. It resets the attempt count and is refused if an identical job is already waiting or running.
- Cancel marks a pending job cancelled at once. A running job is marked "Cancellation requested" and stops at its next safe boundary.
-
queue list --statusacceptspending,running,failed,completeorcancelled.queue rundefaults to 20 jobs and stops after 100 jobs or 20 seconds.
Schema upgrades
After a plugin update, the queue tables are upgraded in small batches from admin screens and WP-CLI, never from visitor requests. Until that finishes, the panel shows "Queue upgrade in progress", new jobs wait, and queue run and queue retry refuse to start. Reload the Tools tab or repeat the command to continue.
Sources: JobRepository, QueueModule.
Diagnostics · Troubleshooting · Cache Warming · AI and MCP · WP-CLI · Settings Reference
GT Performance on WordPress.org · Changelog · Roadmap · GPL-2.0-or-later · Issues and pull requests welcome
Getting started
Caching
Optimization
Delivery
Operations
Reference
Links