perfbase / wordpress
WordPress integration for the Perfbase APM platform
Requires
- php: >=7.4 <8.5
- ext-json: *
- perfbase/php-sdk: 1.0.0
Requires (Dev)
- 10up/wp_mock: ^1.0
- brain/monkey: ^2.6
- mockery/mockery: ^1.6
- phpstan/phpstan: ^2.1
- phpunit/phpunit: ^9
- wp-coding-standards/wpcs: ^3.0
README
Perfbase for WordPress
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.
What it profiles
- Standard HTTP requests
- WordPress admin requests when enabled
- AJAX requests
- WordPress cron runs
- WP-CLI commands
- Additional WordPress metadata through hook-based attribute collection
Requirements
- PHP
7.4to8.5 - WordPress
5.0+ ext-jsonext-perfbase
Installation
Composer-managed WordPress installs
composer require perfbase/wordpress:^1.0
This is the best fit for Bedrock-style or otherwise Composer-managed WordPress projects.
Classic WordPress installs
Until there is a WordPress.org distribution, install the plugin manually:
- Copy or download this package into
wp-content/plugins/perfbase - Run
composer install --no-devinside the plugin directory - Activate the plugin in the WordPress admin
Install the Perfbase extension
The plugin depends on the native Perfbase PHP extension. Install it with:
bash -c "$(curl -fsSL https://cdn.perfbase.com/install.sh)"
Restart PHP-FPM, Apache, Nginx Unit, or any long-lived PHP worker after installing the extension.
Quick start
- 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); // Trace metadata helpers define('PERFBASE_ENVIRONMENT', 'production'); define('PERFBASE_APP_VERSION', '1.0.0');
Configuration model
Configuration priority is:
- Defaults from
ConfigManager - Saved WordPress options (
perfbase_settings) wp-config.phpconstants for the supported core keys
Core settings
| 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 |
Context toggles
| 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 |
Filtering
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/
Admin UI vs runtime filters
The admin page covers the common operational settings:
- API key
- enable profiling
- sample rate
- API URL
- timeout
- proxy
- profile admin
- profile AJAX
- profile cron
- feature flags
- excluded user agents
The runtime also supports the richer per-context include and exclude arrays shown above. Those are the canonical filter model used by the lifecycle classes.
WP-CLI profiling is supported in the runtime, but there is currently no dedicated admin toggle for it.
Feature flags
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 );
How it works
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, the lifecycle stops the span and submits the trace
The plugin also adds context through WordPress hooks such as:
- request and template lifecycle hooks
- database query hooks
- outbound HTTP hooks
wp_diehandling- 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.
Request metadata
The plugin keeps action names low-cardinality and avoids leaking sensitive query parameters.
Core trace attributes
actionin the formatGET /pathuser_idwhen logged inuser_ipuser_agenthostnameenvironmentapp_versionphp_versionhttp_methodhttp_urlhttp_status_code
WordPress-specific attributes
wordpress.versionperfbase.versionwordpress.ajax_actionwordpress.rest_routewordpress.admin_page- template, theme, post, taxonomy, and conditional-tag attributes when available
http_url is stored without the query string. Important WordPress query parameters are broken out into dedicated attributes instead.
Example production setup
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.
Troubleshooting
The plugin says the extension is unavailable
Check that the extension is loaded:
php -m | grep perfbase
php --ini
If needed, reinstall it:
bash -c "$(curl -fsSL https://cdn.perfbase.com/install.sh)"
No traces are appearing
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
High overhead
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
Development
Useful commands:
composer test
composer phpstan
composer phpcs
composer lint
The repository includes unit, integration, and functional tests.
Documentation
Full documentation is available at perfbase.com/docs.
- Docs: perfbase.com/docs
- Issues: github.com/perfbaseorg/wordpress/issues
- Support: support@perfbase.com
License
Apache-2.0. See LICENSE.txt.