Performance Console
Production-oriented WordPress performance diagnostics, incident workflows, profiling, RUM, and guarded database repair.
Install
No release zip yet. The repository archive installs, but the folder name will carry the branch suffix and updates will not flow:
wp plugin install https://github.com/bfrye26/performance-console/archive/refs/heads/main.zipPerformance Console 3.0.0
3.0.0 rename and migration
Performance Console is the new name of WP Performance Inspector. WordPress.org has never hosted the plugin, so the rename also changes the text domain and code prefixes from wpi_/WPI_ to pfc_/PFC_. Existing installs upgrade in place: on activation the plugin renames its seven tables, options, transients, maintenance cron event and MU bootstrap from wpi_* to pfc_* without deleting diagnostic history or backups.
2.2.1 responsive and lifecycle fixes
- The admin suite no longer produces a horizontal scrollbar: the full-bleed background keeps its left bleed without extending past the viewport on the right.
- Uninstall now removes every plugin data store: the seven custom tables,
pfc_*options and transients, the maintenance cron event, the generated MU bootstrap, and plugin-created backup files/directories. - Per-request overhead removed: the MU sampler reads
pfc_secretonly when a signed diagnostic or save-capture request needs it, andpfc_db_versionis autoloaded for existing sites on upgrade. - The MU bootstrap install is atomic (staging file + rename) so an interrupted write can never leave a truncated file in mu-plugins.
- The REST autoload endpoint now uses the Repair Centre's protected-option list, closing the divergence where
blogname,admin_email, roles and widget options were changeable through REST only.
2.2.0 measurement and verification safeguards
- Failed or incomplete rechecks stay open; a successful non-reproducing check moves to observing, not automatically resolved. Safe scans no longer bulk-resolve older deep findings.
- Save rechecks compare the same post, post type, editor, capture kind and user, require a matching WordPress write and successful HTTP response, and keep single-run improvement under observation.
- The early MU bootstrap uses the same tested save matcher as the plugin. Nested block-renderer routes, taxonomy endpoints and unrelated requests no longer match as content saves.
- The MU bootstrap respects plugin activation (including network activation). Declined sampling is not retried by the late profiler.
- RUM uses a pinned, self-hosted web-vitals 6.2.1 build. Version 2 aggregates are separate from legacy measurements; no historical records are deleted. The dashboard displays only version 2 aggregates.
- RUM reports once at the first backgrounding of each sampled visit, with a fresh sample after bfcache restoration. Later interactions on a resumed tab are not included. Values are not a complete page-lifetime/CrUX equivalent. Token refresh and declined-beacon fallback reduce avoidable data loss.
- Plugin impact tests optionally require a visible page phrase in every measured response. This is a content-presence assertion, not proof that JavaScript, forms, checkout or all plugin behavior still works.
- Autoload review suggestions require at least seven days since observation started and 100 recent samples, including 20 frontend and 20 admin samples. Absence is still not proof of disuse; rare workflows need manual checks.
- Database timing includes all retained query timings, while detailed attribution remains bounded and reports saturation. Nested hook times overlap and are not additive callback costs.
- Repair authorization rehashes the selected backup. Re-verification cannot silently replace a changed file's checksum. Dashboard candidate listing does not reread entire exports. Integrity checking is not restore testing or snapshot consistency.
- Scheduled future jobs are not classified as overdue backlog. Missing persistent object caching is an evaluation opportunity rather than a proven fault.
Development checks
Run php tests/run.php for PHP regression tests. Run npm ci --ignore-scripts, npm run build:rum, then npm test for the pinned vendor artifact and JavaScript transport tests. WordPress does not require Node or npm at runtime. Ship assets/vendor/web-vitals/, including its Apache-2.0 license, with the plugin.
After installing this update, open the Performance Console admin page to refresh its MU bootstrap and purge cached HTML through your existing page-cache/CDN controls so visitors receive the new script dependency. The RUM panel starts with version-2 data only. On Windows, scripts/build-release.ps1 builds a runtime-only ZIP and refuses to overwrite an existing archive.
See IMPROVEMENT-PLAN.md for the remaining work toward wider compatibility and guided remediation. This release is the trust-and-measurement foundation, not a universal automatic optimizer.
2.1.1 capture workflow polish
- Rebuilds the Slow Save Profiler setup as a focused, responsive control surface with clear manual-save and autosave choices.
- Adds distinct ready and armed states, concise next-step guidance, and stronger content-safety messaging.
- Improves keyboard focus, semantic form controls, assistive-technology output, and supporting-text contrast.
2.1.0 slow-save diagnostics
- Adds a one-click Capture one real save workflow for manual editor saves or autosaves.
- Captures the next matching classic editor, block editor REST, Quick Edit, product, or custom-post-type save in the same administrator browser.
- Ranks directly attributed database and outbound HTTP work by plugin/theme/core component and records exact query evidence.
- Times save-specific WordPress hooks and lists the components registered on them as clearly labelled suspects, without claiming unmeasured callback-level attribution.
- Uses a signed, HttpOnly, SameSite capture cookie that expires after ten minutes and disarms after one matching request; manual captures ignore autosaves.
- Stores only safe save context such as request kind, post type and numeric ID—never post titles, content, custom-field values, or request bodies.
2.0.1 correlated plugin profiling
- Measures plugin impact from the PHP time saved by WordPress for each exact signed probe, rather than from total loopback-request duration.
- Signs and verifies the probe ID and excluded plugin, then matches both to the persisted diagnostic run before accepting a sample.
- Calculates the result from five paired A/B differences and exposes the individual deltas, median absolute deviation, noise floor and repeatability verdict.
- Shows whether each recent request used all plugins or a private plugin exclusion, making the experiment auditable.
- Treats unstable or small differences as “No repeatable plugin cost detected” instead of assigning ordinary request jitter to the selected plugin.
2.0.0 incident workflow and trustworthy experiments
- Groups repeated route evidence into root-cause incidents with occurrence counts, affected routes, confidence and lifecycle history.
- Adds one-click recheck, snooze, resolve and accepted-risk actions without discarding evidence.
- Requires a repeat observation before passive one-off spikes become confirmed incidents and expires stale passive incidents after seven days.
- Filters database daemons and expected compatibility probes so Performance Console does not report its own inspection noise as site failures.
- Adds cache-safe client-side RUM sampling, single-use route-bound tokens, rate limiting, route-group attribution and histogram-based p75 reporting.
- Alternates five private plugin A/B pairs after warm-up and rejects comparisons when the response type or size changes materially.
- Loads heavy diagnostic modules only for Performance Console admin, REST and CLI work, and renders one admin view per request.
- Adds representative custom-post-type route probes, configurable deep-scan URLs, responsive incident cards and an executable regression test harness.
- Uses MariaDB-compatible primary-key discovery so resumable backups no longer emit one SQL error per table.
1.10.0 managed index ownership
- Accepts managed-index registrations from active plugins through
pfc_managed_database_indexes. - Prefers a plugin's canonical index name when present, otherwise its highest-priority registered legacy alias.
- Shows plugin ownership and canonical-name state in duplicate-index repair plans.
- Revalidates ownership and keep/drop direction before executing duplicate-index DDL.
1.9.2 live PRIMARY KEY dependency repair
- Core-column repairs now inspect the actual live PRIMARY KEY, not only WordPress' expected key. This fixes tables where a plugin/migration has placed a normally-nullable core column such as
wp_usermeta.meta_keyinside a custom/composite PRIMARY KEY. - If the selected column cannot be corrected while the malformed live key remains, Performance Console atomically drops the live PRIMARY KEY, applies the exact WordPress column definition, and restores WordPress' expected PRIMARY KEY.
- The SQL shown under Preview SQL is generated by the same dependency planner used by the repair action, so the preview reflects the complete ALTER rather than only the selected column fragment.
- PRIMARY KEY repair remains dependency-aware for missing and mismatched core keys and retains NULL, duplicate and signed-to-unsigned safety preflights.
- Repair definitions continue to come from the exact schema shipped by the installed WordPress version.
1.8.0 CGM Suite UI
The Performance Console admin interface follows the CGM Suite's compact WordPress-admin design language, with a calm diagnostic surface, clear status colours, accessible navigation, incident cards, cleaner tables/forms and responsive layouts. The interface is organized into Overview, Incidents, Database, Profiling, Monitoring and System views. Existing deep links such as Database Backups and the InnoDB Transaction Manager remain functional and automatically activate the Database view.
1.7.0 InnoDB transaction remediation
The Repair Centre now includes a live InnoDB Transaction Manager. When a schema/index/table repair is blocked by an open InnoDB transaction, Performance Console shows the owning MySQL thread, transaction age/state, connection user/host/database, rows locked/modified, normalized SQL, and blocker/waiter relationships. Eligible stuck or abandoned connections can be terminated from wp-admin with explicit acknowledgement that their uncommitted work will be rolled back. Very old or large transactions require a second high-risk acknowledgement because rollback itself can be expensive. Performance Console never terminates its own connection, recognized server/system/replication sessions, or transactions already rolling back.
CLI equivalents are wp performance innodb-transactions and wp performance innodb-terminate <thread-id> --rollback-confirmed.
1.6.1 backup performance update
Browser database backups now use adaptive high-throughput export steps. Instead of booting WordPress once for every 100 rows, one REST step processes multiple database chunks until a bounded time or output-byte budget is reached. Initial chunk size uses MySQL/MariaDB AVG_ROW_LENGTH, then continuously adapts from actual SQL output size. Narrow tables can export thousands of rows per query while wide LONGTEXT tables automatically shrink their batches. Composite primary keys use keyset pagination, eliminating growing OFFSET scans on common relationship/queue tables. The backup UI now reports per-step throughput, adaptive batch size and estimated current-table progress.
The exporter remains resumable and intentionally yields before ordinary proxy/FastCGI request limits. WP-CLI remains the preferred option for extremely large databases, but it uses the same faster state machine.
Performance Console is a production-oriented WordPress diagnostic and remediation suite. It is designed to identify why WordPress is slow or unstable, attribute expensive work to the responsible component, detect database and plugin faults, and offer bounded fixes where they can be applied safely.
Major diagnostics
Database health
- compares required WordPress core tables, columns and indexes against the schema shipped by the installed WordPress version
- detects missing core tables, missing core columns and missing core indexes
- detects large tables without primary keys and exact duplicate indexes
- checks table engines, collation drift, fragmentation/free space and auto-increment exhaustion risk
- deep engine-aware
CHECK TABLEintegrity checks across WordPress, plugin and custom tables with large-table safety gates - reports MySQL/MariaDB connection pressure, long-running processes, lock-related processes and global slow-query signals
- reports InnoDB buffer-pool efficiency, row-lock waits, recent deadlock/foreign-key-error signals, history-list pressure and pending I/O when permissions allow
- detects disk temporary-table pressure, table scans/full joins, aborted connections and server configuration risks
- guarded orphan detection for post meta, comment meta, user meta, term meta, term relationships and term taxonomy
- expired-transient and transient-volume analysis
- autoload footprint analysis with sampled option-access evidence
Slow queries and request profiling
- one-request manual-save and autosave capture for classic, REST/block editor, Quick Edit, product and custom-post-type writes
- save-specific hook totals plus ranked plugin/theme/core query and outbound HTTP attribution
- low-rate sampled request timing for production trend data
- signed deep route diagnostics for full query traces
- normalized SQL fingerprints rather than raw SQL values by default
- duplicate/N+1 query pattern detection
- cumulative and per-query cost analysis
- plugin/theme/core, file and line attribution
- safe
EXPLAINanalysis for eligible reads - flags full scans, high row estimates, filesorts, temporary tables, unused possible keys, expensive postmeta patterns, wildcard searches,
ORDER BY RAND(),SQL_CALC_FOUND_ROWSand oversized result patterns - blocking outbound HTTP timing and attribution
- hook and WordPress bootstrap phase timing on diagnostic requests
- PHP fatal/database error capture associated with the profiled request
Plugins and WordPress runtime
- active/network plugin inventory and compatibility requirements
- Recovery Mode paused-plugin detection
- PHP fatal, warning, deprecation, memory, timeout and database error fingerprints from available logs
- per-plugin included-file and callback/hook pressure signals
- estimated plugin autoload/database footprint with conservative prefix attribution
- overlapping cache/optimization/SEO responsibility detection
- private signed plugin-exclusion A/B requests without deactivating the plugin for visitors
- diagnostic-response verification so CDN/page-cache responses are not treated as WordPress benchmarks
Jobs, cache, frontend and server
- WP-Cron backlog, duplicate/short-interval events and oversized cron state
- bounded Action Scheduler diagnostics for WooCommerce and other queue users
- persistent object-cache/drop-in detection, feature support and round-trip checks
- WordPress page-cache health integration where available
- PHP, OPcache, filesystem and selected MySQL/MariaDB configuration checks
- frontend HTML/resource pressure, duplicate resources, third-party hosts, plugin/theme asset ownership, DOM size, image-dimension and lazy-loading issues
- sampled RUM aggregation for TTFB, FCP, LCP, INP and CLS
- update/activation/theme-change history and regression correlation
Database backups and guided maintenance
Version 1.6 adds a Database Backups area directly above the Repair Centre. Performance Console can create a private logical export of all WordPress-prefixed tables or the entire current database. Browser exports are resumable and write rows in bounded batches; tables with a single numeric primary key use cursor pagination instead of ever-growing OFFSET queries.
Completed backups are verified with a completion marker and SHA-256 checksum. Downloads require an authenticated administrator request. Performance Console prefers a writable location outside the detected web root and falls back to a randomized private directory protected by deny rules when necessary. These exports contain table schema and row data only; they do not include database users/grants, server configuration, routines, triggers/events or a host/filesystem snapshot.
A recent verified Performance Console backup can be selected directly from any repair that requires a backup. Administrators can alternatively confirm an independently verified external backup or storage snapshot. Previously CLI-only cli-review findings now expose a guarded Run Maintenance Fix workflow in wp-admin. This requires maintenance-window acknowledgement plus the same backup, danger/data-loss, table-size, online-DDL, lock and disk-space gates used by the repair engine. WP-CLI remains the preferred route for the largest tables because a browser request can still be interrupted by PHP/FastCGI/proxy time limits.
WP-CLI backup commands:
wp performance database-backup --scope=wordpress
wp performance database-backup --scope=full
wp performance database-backups
Storage-engine aware diagnostics and maintenance
Version 1.4 includes an explicit storage-engine capability and guided InnoDB recovery layer. The scanner reads SHOW ENGINES from the live MySQL/MariaDB server, reports which engines are available/default, and applies different checks and repair rules per engine rather than treating all tables alike.
- InnoDB:
CHECK TABLE, InnoDB buffer-pool/lock/deadlock/history diagnostics,ANALYZE TABLE, and reviewedOPTIMIZE TABLE/rebuild support.REPAIR TABLEis never offered for InnoDB. Corruption is reported with backup/rebuild/restore/engine-recovery guidance. - MyISAM: CHECK/REPAIR/ANALYZE/OPTIMIZE support with table-size safety gates and explicit maintenance actions.
- Aria (MariaDB): CHECK/REPAIR/ANALYZE/OPTIMIZE support with the same production safety gates.
- ARCHIVE: CHECK and reviewed REPAIR/OPTIMIZE support when appropriate.
- CSV: integrity checks are supported, but automatic repair is intentionally blocked because a CSV repair may discard rows after the first damaged record.
- MEMORY/HEAP: metadata/size/schema inspection only; no fake durability/repair actions are offered.
- NDB/NDBCLUSTER: metadata and recognized ANALYZE support, while recovery/topology work is left to cluster tooling.
- Unknown/plugin engines (including RocksDB/MyRocks variants): diagnostic metadata is retained, but Performance Console does not guess at repair commands it cannot verify.
Deep integrity scans use an engine-supported CHECK TABLE path on size-safe tables and record the engine alongside every result. EXTENDED checks are never run automatically.
Guided InnoDB recovery (1.4)
- parses the latest InnoDB deadlock into normalized queries and involved tables without persisting the raw status dump
- builds an active blocker/waiter graph from Performance Schema, with legacy INFORMATION_SCHEMA fallback when available
- reports long transactions, purge-history pressure, buffer-pool sizing/hit ratio, redo-capacity signals and emergency
innodb_force_recoverystate - provides a read-only recovery preflight for a selected InnoDB table: integrity evidence, index inventory, foreign keys, online-DDL capability, lock state and disk-space margin
- identifies a secondary BTREE index when integrity output names it and can rebuild that index with an explicit
ALGORITHM=INPLACE, LOCK=NONEoperation - refuses automatic FULLTEXT, SPATIAL, HASH, expression, invisible or ignored-index rebuilds
- supports an advanced InnoDB table rebuild path through
ALTER TABLE ... FORCE, ALGORITHM=INPLACE, LOCK=NONE; it never silently falls back toALGORITHM=COPY - requires explicit confirmation of a verified current database backup/snapshot before schema, repair, optimize or InnoDB rebuild mutations
- fails fast when active lock waits or long-running InnoDB transactions make DDL unsafe
- estimates temporary disk-space requirements when the database datadir is visible to PHP and warns when host-level space cannot be verified
- automatically runs post-repair
CHECK TABLEandANALYZE TABLE, and verifies rebuilt indexes exist - generates conservative review-only index candidates for simple single-table slow queries; candidates are never created automatically
Emergency innodb_force_recovery is diagnostic-only. Performance Console never enables it and never describes it as a repair mechanism; use it only as part of controlled data extraction/recovery.
Database Repair Centre
Repairs are explicit. Nothing destructive runs automatically.
Safe/bounded fixes
- delete expired transients in bounded batches
- change the autoload flag for sampled, non-core options after review
- undo supported autoload changes
- remove verified orphaned post/comment/user/term metadata and term relationships in bounded batches
- store bounded rollback snapshots before orphan cleanup and offer an Undo action when the snapshot is complete
Reviewed fixes
- add missing WordPress core columns and indexes using the exact definition parsed from the installed WordPress schema
- preflight primary/unique-key repairs for duplicate values
- size-gate schema ALTER operations in wp-admin
- engine-aware
REPAIR TABLEsupport for MyISAM, MariaDB Aria and ARCHIVE under conservative safety gates; CSV repair remains manual because of data-loss risk - explicit
ANALYZE TABLEandOPTIMIZE TABLEoperations under conservative size limits
High-review and deliberately manual
- creating an empty schema for a missing core table is available only as a high-review action with a verified-backup requirement and explicit acknowledgement that it does not restore lost records
- dropping plugin-defined duplicate indexes
- large table ALTER/OPTIMIZE operations in wp-admin
- storage-engine conversions, collation conversions and other potentially locking migrations
- InnoDB corruption recovery
These cases provide evidence and a recommended maintenance path instead of pretending a one-click production repair is safe. Large operations can be deliberately invoked through WP-CLI with --force-large during an appropriate maintenance window.
WP-CLI
wp performance self-test
wp performance scan
wp performance scan --deep
wp performance database --deep
wp performance database-engines
wp performance database-repairs
wp performance database-fix cleanup_expired_transients --limit=1000
wp performance database-fix cleanup_orphans --type=postmeta --limit=500
wp performance database-fix repair_core_schema --backup-confirmed
wp performance database-fix repair_core_schema --backup-confirmed --force-large
wp performance innodb-preflight wp_postmeta
wp performance innodb-rebuild-index wp_example lookup_key --backup-confirmed
wp performance database-fix rebuild_innodb_table --table=wp_example --backup-confirmed --force-large
wp performance profile https://example.com/article/ --runs=3
wp performance plugin-impact https://example.com/article/ plugin/plugin.php --runs=5
wp performance issues --severity=critical
Production safety
The server profiler defaults to a very small sampled fraction of traffic. Those sampled requests can collect query timings for trend analysis, while full traces/backtraces, one-request save captures and private plugin-exclusion tests require short-lived signed authorization. Sampling can be set to zero. Save capture observes the administrator's real write exactly once; it never replays that write or disables plugins during saving. Diagnostic tracing adds overhead, so save captures are for cause ranking rather than clean latency benchmarking.
Large-table exact checks are skipped in ordinary web scans. Expensive integrity/orphan operations are deep-mode operations and are size-gated. Telemetry uses dedicated tables, bounded retention and low-cardinality route classes so a large publishing site does not create one metric series per article URL.
The plugin does not overwrite db.php, object-cache.php or advanced-cache.php. It does not automatically drop indexes, convert table engines, convert collations, restore missing data or run unrestricted schema changes.
See docs/PRODUCTION.md before deployment to a high-traffic production site.