WordPress integration for Perfbase.
This plugin is a thin adapter over perfbase/php-sdk. It detects the current WordPress execution context, starts and stops trace spans through the shared SDK, and adds WordPress-specific metadata along the way.
- Standard HTTP requests
- WordPress admin requests when enabled
- AJAX requests
- WordPress cron runs
- WP-CLI commands
- Additional WordPress metadata through hook-based attribute collection
- PHP
>=7.4 <8.5 - WordPress
5.0+ ext-curlext-jsonext-perfbase
composer require perfbase/wordpress:^1.0This is the best fit for Bedrock-style or otherwise Composer-managed WordPress projects.
Install the plugin from WordPress.org when available, or upload the perfbase-<version>.zip asset from GitHub Releases through the WordPress admin plugin installer.
Do not use GitHub's automatically generated "Source code" archives for a classic WordPress install. Those archives are source snapshots for developers and do not include production Composer dependencies.
For manual source installation:
- Copy or download this package into
wp-content/plugins/perfbase - Run
composer install --no-dev --optimize-autoloaderinside the plugin directory if you are installing from source - Activate the plugin in the WordPress admin
The plugin depends on the native Perfbase PHP extension. Installing that extension requires shell/server access and permission to copy a native extension into PHP's extension directory and add an ini file. Perfbase for WordPress is intended for advanced or server-managed WordPress environments. Many shared hosting and restricted managed WordPress environments do not support custom PHP extensions; in those environments the plugin can be installed, but profiling will not run until the extension is available.
Automated installer for supported server environments:
bash -c "$(curl -fsSL https://cdn.perfbase.com/install.sh)"The installer performs the same download, checksum, copy, ini-file, and verification steps automatically.
Manual extension installation with wget:
Find the PHP major/minor version and CPU architecture:
php -r 'echo PHP_MAJOR_VERSION.".".PHP_MINOR_VERSION.PHP_EOL;'
uname -mUse amd64 for x86_64, and arm64 for aarch64 or Apple Silicon. Choose the URL pattern for your server:
Debian/Ubuntu and most glibc Linux distributions:
wget https://cdn.perfbase.com/extension/latest/perfbase-8.3-linux-amd64-gnu-release.so
wget https://cdn.perfbase.com/extension/latest/perfbase-8.3-linux-amd64-gnu-release.so.sha256sum.txt
sha256sum -c perfbase-8.3-linux-amd64-gnu-release.so.sha256sum.txtAlpine Linux:
wget https://cdn.perfbase.com/extension/latest/perfbase-8.3-linux-amd64-musl-release.so
wget https://cdn.perfbase.com/extension/latest/perfbase-8.3-linux-amd64-musl-release.so.sha256sum.txt
sha256sum -c perfbase-8.3-linux-amd64-musl-release.so.sha256sum.txtmacOS:
wget https://cdn.perfbase.com/extension/latest/perfbase-8.3-darwin-arm64-release.dylib
wget https://cdn.perfbase.com/extension/latest/perfbase-8.3-darwin-arm64-release.dylib.sha256sum.txt
sha256sum -c perfbase-8.3-darwin-arm64-release.dylib.sha256sum.txtReplace 8.3 with your PHP major/minor version and replace amd64 with arm64 when using ARM64 Linux.
Find PHP's extension directory and loaded ini scan directories:
php -i | grep '^extension_dir'
php --iniCopy the extension binary into PHP's extension directory, then create perfbase.ini in one of the loaded ini scan directories:
extension=perfbase.extReplace perfbase.ext with the downloaded filename, such as perfbase.so or perfbase.dylib.
Restart PHP-FPM, Apache, Nginx Unit, or any long-lived PHP worker after installing the extension, then verify it:
php -m | grep perfbaseFor a specific pinned build instead of the mutable latest build, replace /extension/latest/ with a versioned path such as /extension/v123/.
- Activate the plugin
- Go to
Settings -> Perfbase - Add your Perfbase API key
- Enable profiling
- Start with a sample rate like
0.1
If you prefer configuration in code, define the supported constants in wp-config.php:
define('PERFBASE_ENABLED', true);
define('PERFBASE_API_KEY', 'your-api-key-here');
define('PERFBASE_SAMPLE_RATE', 0.1);
define('PERFBASE_API_URL', 'https://ingress.perfbase.cloud');
define('PERFBASE_TIMEOUT', 10);
define('PERFBASE_PROXY', '');
define('PERFBASE_FLAGS', \Perfbase\SDK\FeatureFlags::DefaultFlags);
define('PERFBASE_PROFILE_HTTP_STATUS_CODES', '200-299,500-599');
define('PERFBASE_DEBUG', false);
define('PERFBASE_LOG_ERRORS', true);
// Trace metadata helpers
define('PERFBASE_ENVIRONMENT', 'production');
define('PERFBASE_APP_VERSION', '1.0.0');Configuration priority is:
- Defaults from
ConfigManager - Saved WordPress options (
perfbase_settings) wp-config.phpconstants for the supported core keys
| Setting | Default | Purpose |
|---|---|---|
enabled |
false |
Global on/off switch |
debug |
false |
Surface profiling failures instead of failing open |
log_errors |
true |
Log profiling failures when debug is off |
api_key |
'' |
Perfbase API key |
api_url |
https://ingress.perfbase.cloud |
Receiver base URL |
sample_rate |
0.1 |
Sampling rate between 0.0 and 1.0 |
timeout |
10 |
Submission timeout in seconds |
proxy |
'' |
Optional outbound proxy |
flags |
FeatureFlags::DefaultFlags |
Perfbase extension flags |
profile_http_status_codes |
array_merge(range(200, 299), range(500, 599)) |
HTTP response codes that should be submitted |
| Setting | Default | Notes |
|---|---|---|
profile_admin |
false |
Skip admin by default |
profile_ajax |
true |
AJAX requests are profiled by default |
profile_cron |
true |
Cron requests are profiled by default |
profile_cli |
false |
WP-CLI support exists but is off by default |
The runtime filter model uses nested context filters:
[
'include' => [
'http' => ['*'],
'ajax' => ['*'],
'cron' => ['*'],
'cli' => ['*'],
],
'exclude' => [
'http' => [
'/wp-content/uploads/*',
'/favicon.ico',
],
'ajax' => [],
'cron' => [],
'cli' => [],
],
'exclude_user_agents' => [
'bot',
'crawler',
'spider',
],
]http, ajax, cron, and cli all support:
*and.*wildcard matching- glob-style patterns through
fnmatch() - regex patterns like
/^POST \/wp-admin/
The admin page covers the common operational settings:
- API key
- enable profiling
- sample rate
- API URL
- timeout
- proxy
- profile admin
- profile AJAX
- profile cron
- profile WP-CLI
- HTTP status codes to submit
- feature flags
- HTTP include patterns
- HTTP exclude patterns
- excluded user agents
The admin UI writes the same nested include / exclude structure used by the runtime. It currently exposes the HTTP filter lists directly and preserves any existing AJAX, cron, and CLI filter arrays already present in saved config.
The HTTP status code setting accepts comma-separated values or ranges such as 200-299, 500-599, 404. The default is 200-299, 500-599. Leave it empty if you want to drop all HTTP trace submissions.
The plugin passes SDK feature flags straight through to the Perfbase extension.
Common flags exposed in the admin UI include:
UseCoarseClockTrackCpuTimeTrackPdoTrackHttpTrackCachesTrackMongodbTrackElasticsearchTrackQueuesTrackFileOperations
Programmatic configuration can also use the broader flag set from perfbase/php-sdk.
Example:
define(
'PERFBASE_FLAGS',
\Perfbase\SDK\FeatureFlags::UseCoarseClock |
\Perfbase\SDK\FeatureFlags::TrackCpuTime |
\Perfbase\SDK\FeatureFlags::TrackPdo
);The plugin creates one lifecycle object per request context:
HttpRequestLifecycleAjaxRequestLifecycleCronLifecycleCliLifecycle
At a high level:
- The plugin boots on
plugins_loaded - It loads config and attempts to create the shared SDK client
- On
init, it detects the current context and starts the appropriate lifecycle - During the request, lightweight hooks add WordPress-specific attributes
- On shutdown, HTTP requests are only submitted if their status code is in
profile_http_status_codes - On
shutdown, the lifecycle stops the span and submits the trace
The plugin also adds context through WordPress hooks such as:
- outbound HTTP hooks
- theme and plugin lifecycle hooks
- user, post, comment, REST API, and WooCommerce hooks when available
Cache profiling itself is handled by the native Perfbase extension via feature flags rather than by WordPress cache hooks.
Perfbase can send:
- function call trees, function names, source file paths and line numbers, timing, CPU, memory, and host resource metrics
- host operating system, kernel, hostname, CPU architecture, CPU details, disk capacity details, memory usage, CPU usage, disk I/O, and network I/O samples
- capped process-list snapshots when enabled, containing process ID, executable basename, OS user, CPU usage, memory usage, and process runtime, without command-line arguments
- additional native trace metadata such as normalized SQL query text, database DSN/host/database/username/port metadata, MongoDB or Elasticsearch query/filter payload summaries, Redis or Memcached keys and fields, HTTP URL or URI metadata that may include query strings depending on the PHP API or HTTP library used, HTTP method/status/timing/byte-count metadata, file paths and file operation metadata, mail recipient and subject metadata, shell/process command strings, AWS operation names, OPcache and JIT statistics, PHP error or exception samples, compiled file paths, magic method counts, and truncated function argument values when argument capture is separately configured. These fields depend on enabled extension features, loaded PHP libraries, and which code paths run during the trace
- WordPress request metadata such as action name, HTTP method, request URL without query string, HTTP status code, user IP address, user agent, logged-in user ID when available, hostname, environment, application version, PHP version, WordPress version, and Perfbase plugin version
- WordPress context metadata such as AJAX action, REST route, admin page, post/page identifiers, post type/status, taxonomy context, template and theme information, conditional page type flags, plugin lifecycle context, and WooCommerce page, cart, product, or order context when available
- operational summaries such as memory usage, database query count and timing summaries when available, and sanitized outbound HTTP request metadata when HTTP tracking is enabled
Perfbase does not collect:
- source code
- request bodies, full POST payloads (
$_POST), arbitrary form fields, or uploaded file contents - cookie values (
$_COOKIE) or PHP session data ($_SESSION) - authorization header values
- passwords, API keys, nonces, or session IDs from WordPress request, cookie, or session data
- command-line arguments for process-list snapshots
Feature flags control the extra native trace metadata listed under "Perfbase can send", including outbound HTTP URLs or URIs with query strings for some HTTP libraries and truncated function argument values if argument capture is separately configured. Review enabled Perfbase extension feature flags before profiling sensitive workloads, especially flags that capture arguments, errors, exceptions, database/cache/HTTP/file metadata, mail metadata, process metadata, OPcache metadata, or host resource metadata.
The plugin keeps action names low-cardinality and avoids leaking sensitive query parameters.
actionin the formatGET /pathuser_idwhen logged inuser_ipuser_agenthostnameenvironmentapp_versionphp_versionhttp_methodhttp_urlhttp_status_code
wordpress.versionperfbase.versionwordpress.ajax_actionwordpress.rest_routewordpress.admin_page- template, theme, post, taxonomy, and conditional-tag attributes when available
http_url for the inbound WordPress request is stored without the query string. Important WordPress query parameters are broken out into dedicated attributes instead. Native HTTP metadata may still include full outbound URLs or URIs with query strings depending on enabled extension features and the HTTP library used.
Perfbase does not collect:
- source code
- request bodies, full POST payloads (
$_POST), arbitrary form fields, or uploaded file contents - cookie values (
$_COOKIE) or PHP session data ($_SESSION) - authorization header values
- passwords, API keys, nonces, or session IDs from WordPress request, cookie, or session data
- command-line arguments for process-list snapshots
Database metadata added by the WordPress plugin is limited to aggregate query counts and timing information when available. Native HTTP metadata can include outbound URLs or URIs with query strings. The native profiler may capture additional context depending on enabled Perfbase extension feature flags and application code.
For a typical production site:
define('PERFBASE_ENABLED', true);
define('PERFBASE_API_KEY', getenv('PERFBASE_API_KEY'));
define('PERFBASE_SAMPLE_RATE', 0.02);
define('PERFBASE_TIMEOUT', 5);
define(
'PERFBASE_FLAGS',
\Perfbase\SDK\FeatureFlags::UseCoarseClock |
\Perfbase\SDK\FeatureFlags::TrackCpuTime |
\Perfbase\SDK\FeatureFlags::TrackPdo
);That gives you low overhead while still capturing a useful stream of production traces.
Check that the extension is loaded:
php -m | grep perfbase
php --iniIf the extension is missing, repeat the manual extension installation steps above or run the automated installer on a supported server:
bash -c "$(curl -fsSL https://cdn.perfbase.com/install.sh)"Check these first:
- profiling is enabled
- the API key is present
- the extension is loaded
- the current request type is allowed by your profile toggles
- your sample rate is not set too low
- the request is not blocked by filters or excluded user-agent rules
To reduce overhead:
- lower
sample_rate - use
UseCoarseClock - disable feature flags you do not need
- avoid profiling admin traffic unless you need it
- narrow your include filters
Useful commands:
composer test
composer phpstan
composer phpcs:syntax
composer phpcs
composer lintThe repository includes unit, integration, and functional tests. composer phpcs is the focused WordPress security gate for release checks; use composer phpcs:syntax for the lightweight PHP syntax-only check.
Full documentation is available at perfbase.com/docs.
- Docs: perfbase.com/docs
- Issues: github.com/perfbaseorg/wordpress/issues
- Support: support@perfbase.com
Build the installable release ZIP from a clean checkout by passing the tag or release version:
bin/build-release-zip v1.2.3The generated ZIP is written to dist/perfbase-<version>.zip and includes production Composer dependencies only. Use this same ZIP for GitHub Releases and WordPress.org distribution.
Release checklist:
- Run
composer test,composer phpstan,composer phpcs:syntax, andcomposer phpcs. - Tag the release as
v<version>, for examplev1.2.3. - Push the tag. GitHub Actions builds, verifies, and uploads the installable ZIP to the GitHub Release.
- Use the same generated package contents for WordPress.org SVN.
To reproduce the tagged package locally:
bin/build-release-zip v1.2.3
bin/verify-release-zip dist/perfbase-1.2.3.zip v1.2.3bin/build-wporg-zip remains available as a compatibility wrapper around bin/build-release-zip.
GPL-2.0-or-later. See LICENSE.txt.