Scripts to benchmark Object Cache Pro and Relay against various plugins.
Make sure k6 is installed. All tests can be run locally using k6 run or in the cloud using k6 cloud.
When Object Cache Pro is installed, custom metrics for WordPress, Redis and Relay are automatically collected. For other plugins, use the k6-metrics.php as a must-use plugin to capture more metrics.
Fetches all WordPress sitemaps and iterates through URLs sequentially for reproducible runs.
k6 run k6-wp.js --env SITE_URL=https://example.com
k6 run k6-wp.js --vus=100 --duration=10m --env SITE_URL=https://example.com| Variable | Required | Description |
|---|---|---|
SITEMAP_URL |
No | Custom sitemap URL (default: {SITE_URL}/wp-sitemap.xml). |
PROFILE |
No | Named benchmark profile (see Profiles). Omit to use the site's default configuration. |
| Variable | Required | Description |
|---|---|---|
SITE_URL |
Yes | Base URL of the site, without trailing slash |
BYPASS_CACHE |
No | When set, sends cookies that bypass full-page caches |
PROJECT_ID |
No | k6 Cloud project ID |
K6_SECRET |
No | Secret token for the reset endpoint. When set, setup() flushes the object cache, transients, and WooCommerce sessions before the run. Must match K6_SECRET in wp-config-benchmark.php. |
Profiles select which object cache drop-in and client to use for a run, applied via HTTP request headers. Omitting PROFILE uses the site's PHP configuration unchanged.
k6 run k6-wp.js --env SITE_URL=https://example.com --env PROFILE=ocp-relayBase
| Profile | Drop-in | Client |
|---|---|---|
none |
WordPress built-in memory cache | — |
ocp-relay |
Object Cache Pro | Relay |
ocp-phpredis |
Object Cache Pro | PhpRedis |
roc-phpredis |
Redis Object Cache | PhpRedis |
roc-relay |
Redis Object Cache | Relay |
Capture profiles — use with har-replay.js + the capture mu-plugin (stubs/k6-capture.php) to record one Redis command trace (corpus) per configuration. Each flips exactly one capture-time knob — one that changes which commands run, so it can't be reproduced at replay and needs its own corpus. All capture under PhpRedis (Relay's client-side cache would drop round-trips and record an incomplete stream).
| Profile | knob vs baseline | command-stream effect |
|---|---|---|
capture-baseline |
— | plain keys, single alloptions GET, no prefetch |
capture-hfe |
group_flush=atomic |
groups-as-hashes + hash-field-expiry: every GET→HGET, sets become HFE field writes — changes reads, not just flushes |
capture-prefetch |
prefetch=true |
batched key preload pipeline at request start (warm the site first) |
Benchmark profiles — direct A/B comparisons against the live site (k6-wp.js).
| Profile | knob | value |
|---|---|---|
split-off |
split_alloptions |
false |
split-on |
split_alloptions |
true |
prefetch-off |
prefetch |
false |
prefetch-on |
prefetch |
true |
client-phpredis |
client | phpredis |
client-relay |
client | relay |
client-relay-adaptive |
client | relay + relay.adaptive on |
php-lz4 |
serializer + compression | php + lz4 |
php-zstd |
serializer + compression | php + zstd |
igbinary-lz4 |
serializer + compression | igbinary + lz4 |
igbinary-zstd |
serializer + compression | igbinary + zstd |
Profiles are defined in lib/profiles.js. See __data/README.md for all supported headers.