Paired skills.sh/autoskills.sh catalog scans (2026-08-15, reports in granja/_temp/codex-logs/) independently flagged wordpress/agent-skills' wp-performance module as the best net-new find of the whole scan: a measurement-first, backend-only WP diagnostic workflow (WP-CLI doctor/profile, headless Query Monitor, autoload/object-cache/cron checks) — a strong fit since this fleet's 13+ WordPress sites are all headless/jailed with no browser-first profiling access. Adapted from github.com/wordpress/agent-skills (skills/wp-performance) rather than installed verbatim: swapped the upstream's local/SSH assumptions for the fleet's actual `bastille cmd ... su -m www` remote-execution pattern (reusing wordpress-cli-remote-execution's convention exactly), added a jail/site selector step against the real granja/staging/gringo inventory, narrowed the always-collect baseline to four metrics (TTFB, autoload size, object-cache presence, cron health) with fleet-specific context for each, added redaction guidance for Valkey/DB credentials that diagnostic output can surface, and replaced the upstream's hardcoded "WordPress 7.0+" compatibility claim with per-site version verification. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
117 lines
4.3 KiB
Markdown
117 lines
4.3 KiB
Markdown
# Deeper diagnostic tools (still read-only, still backend-only)
|
|
|
|
Load this file only once the four core baseline metrics (TTFB, autoload
|
|
size, object-cache presence, cron health — see `SKILL.md` Step 3) haven't
|
|
explained the symptom. Every command here still goes through the fleet's
|
|
`bastille cmd ... su -m www -c "wp ..."` wrapper from `SKILL.md` Step 2 —
|
|
abbreviated to bare `wp ...` below for readability.
|
|
|
|
## `wp doctor` — quick production-readiness checks
|
|
|
|
Catches common footguns fast: autoload bloat, `SAVEQUERIES`/`WP_DEBUG`
|
|
left on, stale plugin/core versions.
|
|
|
|
```bash
|
|
wp doctor check
|
|
wp doctor list # see available checks
|
|
```
|
|
|
|
Install if missing (this is a write action — confirm it's acceptable
|
|
before running it, per Step 0):
|
|
|
|
```bash
|
|
wp package install wp-cli/doctor-command
|
|
```
|
|
|
|
Checks especially relevant to performance:
|
|
|
|
- `autoload-options-size` — autoloaded-options threshold
|
|
- `constant-savequeries-falsy` / `constant-wp-debug-falsy` — flags
|
|
perf-costly debug constants left on in what should be production
|
|
- cron checks (event count / duplicates)
|
|
|
|
Docs: default checks —
|
|
https://make.wordpress.org/cli/handbook/doctor-default-checks/ ·
|
|
customizing checks —
|
|
https://make.wordpress.org/cli/handbook/guides/doctor/doctor-customize-config/
|
|
|
|
## `wp profile` — hook/stage-level profiling without a browser
|
|
|
|
Install if missing (write action, confirm first):
|
|
|
|
```bash
|
|
wp package install wp-cli/profile-command
|
|
```
|
|
|
|
Recommended sequence:
|
|
|
|
1. **Stage overview** — where time goes across bootstrap/main_query/template:
|
|
```bash
|
|
wp profile stage --fields=stage,time,cache_ratio [--url=<url>]
|
|
```
|
|
2. **Hook hotspots**:
|
|
```bash
|
|
wp profile hook --spotlight [--url=<url>]
|
|
wp profile hook init --spotlight [--url=<url>] # drill into one hook
|
|
```
|
|
3. **Targeted eval**:
|
|
```bash
|
|
wp profile eval 'do_action("init");' --hook=init
|
|
```
|
|
|
|
Use `--url=` to profile a specific site/route on a multisite-adjacent
|
|
setup. `--skip-plugins`/`--skip-themes` can isolate a culprit component,
|
|
but changes real behavior while active — note that in the report if you
|
|
use it, don't silently profile a degraded version of the site.
|
|
|
|
Docs: https://wpcli.dev/docs/profile/stage ·
|
|
https://wpcli.dev/docs/profile/hook ·
|
|
https://wpcli.dev/docs/profile/eval
|
|
|
|
## Query Monitor, used headlessly
|
|
|
|
Query Monitor is normally UI-driven, but it exposes data through
|
|
authenticated REST response headers/envelope — no browser required.
|
|
|
|
1. Confirm the plugin is active: `bastille cmd <jail> test -f
|
|
<site-path>/wp-content/plugins/query-monitor/query-monitor.php`.
|
|
2. Authenticate against the REST API — a nonce, or an Application
|
|
Password (see Redaction in `SKILL.md`: never paste a generated
|
|
Application Password into a report).
|
|
3. Request a REST route and inspect response headers (`x-qm-overview-*`
|
|
etc.), or request an enveloped response (`?_envelope`) to get a `qm`
|
|
property containing DB query details, cache stats, and HTTP API call
|
|
details in one payload.
|
|
|
|
Configuration constants: https://querymonitor.com/help/configuration-constants/ ·
|
|
REST-API-specific docs: https://querymonitor.com/wordpress-debugging/rest-api-requests/ ·
|
|
plugin page: https://wordpress.org/plugins/query-monitor/
|
|
|
|
Guardrails: Query Monitor adds real overhead — don't enable it in
|
|
production without approval. If a hosting platform pre-installs it
|
|
gated behind a capability, you may need `view_query_monitor` granted to
|
|
the authenticating user.
|
|
|
|
## Server-Timing headers (if Performance Lab is present)
|
|
|
|
```bash
|
|
curl -sS -D - -H 'Host: <domain>' http://<jail-ip>/ -o /dev/null | grep -i '^server-timing:'
|
|
```
|
|
|
|
Requires the Performance Lab plugin (or a module of it) enabled —
|
|
https://wordpress.org/plugins/performance-lab/. Don't enable experimental
|
|
modules in production without approval; this is a nice-to-have on top of
|
|
the four core baseline metrics, not a replacement for them.
|
|
|
|
Benchmarking guidance: https://make.wordpress.org/performance/handbook/measuring-performance/benchmarking-server-timing/
|
|
|
|
## General measurement discipline
|
|
|
|
- Always capture a baseline before changing anything.
|
|
- Keep the test scenario fixed — same URL/route, same logged-in-or-not
|
|
state, same underlying data.
|
|
- Prefer multiple samples and a median over a single run.
|
|
|
|
Measuring-performance handbook:
|
|
https://make.wordpress.org/performance/handbook/measuring-performance/
|