Hooks & Filters Reference
This reference is for developers who want to extend or integrate with Warp Performance from a theme’s functions.php, a custom plugin, or a must-use plugin. All hook names are prefixed with WARP_PERFORMANCE_ unless otherwise noted.
Constants
Define these constants before Warp loads (e.g., in wp-config.php or a must-use plugin) to control plugin behavior at the lowest level.
WARP_BYPASS_CACHEconstant
Prevents the current request from being cached or served from cache. The page will always be generated fresh by WordPress.
// In wp-config.php or a must-use plugin
define( 'WARP_BYPASS_CACHE', true );
Use case: maintenance scripts, import tools, or any context where you’re generating pages programmatically and don’t want cache interference.
Bypassing the Cache
WARP_PERFORMANCE_is_cacheablefilter
The final gate before a page is written to cache. Return false to prevent the current page from being cached.
$is_cacheable(bool) — Whether the current page should be cached. Default:true.
add_filter( 'WARP_PERFORMANCE_is_cacheable', function( $is_cacheable ) {
// Don't cache search result pages
if ( is_search() ) {
return false;
}
// Don't cache pages for a specific custom post type
if ( is_singular( 'live_event' ) ) {
return false;
}
return $is_cacheable;
} );
This filter runs inside the WordPress context (after template_redirect), so all conditional tags like is_search(), is_singular(), is_user_logged_in() etc. are available.
WARP_PERFORMANCE_request_urifilter
Modifies the request URI that Warp uses to look up and store cache files. You can normalize or rewrite it before any cache decision is made.
$request_uri(string) — The raw$_SERVER['REQUEST_URI'].
add_filter( 'WARP_PERFORMANCE_request_uri', function( $uri ) {
// Strip a custom tracking parameter from the cache key
$uri = preg_replace( '/[?&]ref=[^&]+/', '', $uri );
return $uri;
} );
WARP_PERFORMANCE_cache_file_pathfilter
Filters the sub-path a cached page is stored under, within Warp’s cache directory. The value you receive is the URL path, already decoded — not a full filesystem path. Warp always builds the final location as <cache dir>/<host>/<your path>/, so this filter cannot move the cache anywhere else on disk.
$path(string) — The URL path of the current request, e.g./blog/hello-world/.
This exists so that a plugin serving several variants of the same URL — a translation plugin, most often — can give each variant its own cache directory.
// Store each language under its own directory
add_filter( 'WARP_PERFORMANCE_cache_file_path', function( $path ) {
$lang = my_plugin_current_language(); // e.g. 'fr'
return $lang ? '/' . $lang . $path : $path;
} );
This filter does not stop a page being cached. Returning an empty string or false does not disable caching — it stores the page at the top of the host’s cache directory instead. Because the cache file name is built from role, currency, device and query string, and carries nothing from the URL, every page you send to the same directory overwrites the last one, and visitors can be served a page they did not request. To stop a page being cached, use WARP_PERFORMANCE_is_cacheable.
Keep the result derived from the URL. Warp’s advanced-cache.php drop-in runs before WordPress loads, so no filter is available to it; it locates a cached page from the raw request URI. Cache purging resolves paths the same way. If your filter returns something the request URI cannot be mapped back to, pages are written to a location nothing ever reads or purges, and every request is a cache miss.
WARP_PERFORMANCE_cache_allowed_hostsfilter
Hostnames that Warp will serve cached pages for. By default only the site’s own host (and its www/bare variant) is allowed. Add extra hosts when the same WordPress serves multiple domains that should share the cache.
$hosts(array) — Allowed hostnames.
add_filter( 'WARP_PERFORMANCE_cache_allowed_hosts', function( $hosts ) {
$hosts[] = 'staging.example.com';
return $hosts;
} );
Cache Keys — Query Strings
WARP_PERFORMANCE_cache_include_queriesfilter
Adds query string parameter names to the include list. Parameters in this list are kept as part of the cache key, so ?lang=fr and ?lang=en are cached as separate pages.
By default, Warp includes: lang, currency, orderby, max_price, min_price, rating_filter, page.
$queries(array) — Query parameter names to keep in the cache key.
add_filter( 'WARP_PERFORMANCE_cache_include_queries', function( $queries ) {
// Cache separately by membership tier
$queries[] = 'tier';
// Cache separately by view mode
$queries[] = 'view';
return $queries;
} );
WARP_PERFORMANCE_cache_file_namefilter
Full control over the cache file name (hash) for the current request. The name is derived from the logged-in state, user role, currency, and included query parameters.
$file_name(string) — The computed cache file name/hash.
add_filter( 'WARP_PERFORMANCE_cache_file_name', function( $file_name ) {
// Add A/B test bucket to cache key
$bucket = $_COOKIE['ab_bucket'] ?? 'default';
return $file_name . '-' . sanitize_key( $bucket );
} );
Logged-in User Caching
WARP_PERFORMANCE_cache_adminsfilter
Controls whether users with administrator capability are served cached pages. Defaults to false (admins always get live pages).
$cache_admins(bool) — Whether to cache pages for admins. Default:false.
add_filter( 'WARP_PERFORMANCE_cache_admins', '__return_true' );
WARP_PERFORMANCE_cache_excluded_rolesfilter
Exclude specific user roles from receiving cached pages. Users with these roles will always get a fresh, uncached page.
$roles(array) — Role slugs to exclude. Default:[].
add_filter( 'WARP_PERFORMANCE_cache_excluded_roles', function( $roles ) {
// Never serve cached pages to premium members
$roles[] = 'premium_member';
return $roles;
} );
WARP_PERFORMANCE_cache_mobilefilter
Programmatically control whether the current request is treated as a mobile request for cache-key purposes.
$is_mobile(bool) — Whether to use the mobile cache variant. Default: detected from config.
add_filter( 'WARP_PERFORMANCE_cache_mobile', function( $is_mobile ) {
// Use a custom mobile detection library
return My_Mobile_Detect::is_mobile();
} );
Compression
WARP_PERFORMANCE_brotli_levelfilter
Sets the Brotli compression level used when writing cached pages (when Brotli caching is enabled and the server supports it). Higher levels compress smaller but take longer to write.
$level(int) — Compression level 1–11. Default:9.
add_filter( 'WARP_PERFORMANCE_brotli_level', function() {
return 11;
} );
Auto-purge & Auto-preload
WARP_PERFORMANCE_auto_purge_urlsfilter
When a post is published or updated, Warp automatically purges a set of URLs (the post URL, homepage, category archives, etc.). Use this filter to add or remove URLs from that list.
$urls(array) — List of URLs that will be purged.$post_id(int) — The ID of the post that triggered the purge.
add_filter( 'WARP_PERFORMANCE_auto_purge_urls', function( $urls, $post_id ) {
// Also purge a custom aggregator page when any post updates
$urls[] = home_url( '/latest-news/' );
// Purge all URLs for a related taxonomy term
$terms = get_the_terms( $post_id, 'topic' );
if ( $terms && ! is_wp_error( $terms ) ) {
foreach ( $terms as $term ) {
$urls[] = get_term_link( $term );
}
}
return $urls;
}, 10, 2 );
WARP_PERFORMANCE_auto_preload_urlsfilter
The list of URLs Warp re-warms right after an automatic purge (post save, comment, etc.). Same signature as auto_purge_urls.
$urls(array) — URLs queued for preload after the purge.$post_id(int) — The post that triggered it.
add_filter( 'WARP_PERFORMANCE_auto_preload_urls', function( $urls, $post_id ) {
$urls[] = home_url( '/latest-news/' );
return $urls;
}, 10, 2 );
Preload Control
WARP_PERFORMANCE_is_url_preloadablefilter
Decide per URL whether the preloader is allowed to warm it. Return false to skip a URL.
$preloadable(bool) — Default:true.$url(string) — The URL being considered.
add_filter( 'WARP_PERFORMANCE_is_url_preloadable', function( $preloadable, $url ) {
// Never preload the huge store locator page
if ( strpos( $url, '/store-locator/' ) !== false ) {
return false;
}
return $preloadable;
}, 10, 2 );
WARP_PERFORMANCE_excluded_post_typesfilter
Post types excluded from preloading and caching decisions (builder templates, attachments, etc.).
$post_types(array) — Excluded post type slugs. Default includesattachment,bricks_template,elementor_libraryand similar builder types.
add_filter( 'WARP_PERFORMANCE_excluded_post_types', function( $post_types ) {
$post_types[] = 'internal_docs';
return $post_types;
} );
WARP_PERFORMANCE_preload_recent_posts_countfilter
How many recent posts are prioritized at the front of the preload queue. Default: 10.
add_filter( 'WARP_PERFORMANCE_preload_recent_posts_count', function() {
return 25;
} );
WARP_PERFORMANCE_preload_terms_capfilter
Maximum number of taxonomy term archives added to the preload queue. Default: 5000 (minimum 500).
add_filter( 'WARP_PERFORMANCE_preload_terms_cap', function() {
return 1000;
} );
WARP_PERFORMANCE_homepage_link_excludesfilter
Path fragments excluded when Warp collects links from the homepage for preloading. Default: ['/author/', '/feed', '/sitemap', '/cdn-cgi/'].
add_filter( 'WARP_PERFORMANCE_homepage_link_excludes', function( $excludes ) {
$excludes[] = '/promo/';
return $excludes;
} );
Purge & Preload Lifecycle Actions
These actions fire during the cache purge/preload lifecycle. Hook into them to trigger your own cache clearing logic (e.g., a Varnish layer, a custom CDN, or an in-memory store).
WARP_PERFORMANCE_purge_url:before / :afteraction
Fires before/after a single URL’s cache is deleted.
$url(string) — The URL being purged.
add_action( 'WARP_PERFORMANCE_purge_url:after', function( $url ) {
my_cdn_purge_url( $url );
} );
WARP_PERFORMANCE_purge_urls:before / :afteraction
Fires before/after a batch of URLs is purged (e.g., on post save).
$urls(array) — The list of URLs being purged.
add_action( 'WARP_PERFORMANCE_purge_urls:after', function( $urls ) {
foreach ( $urls as $url ) {
my_cdn_purge_url( $url );
}
} );
WARP_PERFORMANCE_purge_pages:before / :afteraction
Fires before/after all cached pages are deleted.
add_action( 'WARP_PERFORMANCE_purge_pages:after', function() {
// Log the purge event
error_log( '[MyPlugin] Warp full purge triggered at ' . current_time( 'mysql' ) );
// Clear your own cache layer
my_redis_flush_pages();
} );
WARP_PERFORMANCE_purge_everything:before / :afteraction
Fires before/after a complete cache reset (pages + object cache + OPcache).
add_action( 'WARP_PERFORMANCE_purge_everything:after', function() {
// Notify an external service
wp_remote_post( 'https://my-service.com/cache-cleared', [
'body' => [ 'site' => home_url() ],
] );
} );
WARP_PERFORMANCE_preloaded_urlsaction
Fires after the preload queue successfully warms a batch of URLs. Useful for purging a CDN layer only for pages that were actually regenerated.
$urls(array) — URLs that were successfully preloaded.
add_action( 'WARP_PERFORMANCE_preloaded_urls', function( $urls ) {
my_cdn_purge_urls( $urls );
} );
WARP_PERFORMANCE_queue_drainedaction
Fires when the preload queue finishes processing all pending jobs. No parameters.
add_action( 'WARP_PERFORMANCE_queue_drained', function() {
error_log( '[MyPlugin] Warp preload finished at ' . current_time( 'mysql' ) );
} );
WARP_PERFORMANCE_purge_everythingaction
Fires immediately after WARP_PERFORMANCE_purge_everything:after, as the last step of a full cache reset. Provided for integrations that want a single unsuffixed hook name to listen on; if you are choosing between them, use :after.
add_action( 'WARP_PERFORMANCE_purge_everything', function() {
my_cdn_purge_all();
} );
HTML Output Filtering
WARP_PERFORMANCE_optimization:afterfilter
Filters the complete HTML string after all Warp optimizations have been applied but before the page is written to cache and sent to the browser. This is the best place to make final HTML modifications.
$html(string) — The fully optimized HTML.
add_filter( 'WARP_PERFORMANCE_optimization:after', function( $html ) {
// Inject a custom comment
$html = str_replace( '</body>', '<!-- My Plugin Active --></body>', $html );
return $html;
} );
WARP_PERFORMANCE_footprintfilter
Modifies the HTML comment Warp appends at the bottom of cached pages.
$comment(string) — The HTML comment string. Default:<!-- Powered by Warp Performance for lightning-fast performance. Learn more: https://WarpPerformance.com. Cached at 1756400000 -->, where the trailing number is the Unix timestamp the page was cached at.
// Remove the footer comment entirely
add_filter( 'WARP_PERFORMANCE_footprint', '__return_empty_string' );
// Or customize it
add_filter( 'WARP_PERFORMANCE_footprint', function( $comment ) {
return '<!-- Cached & optimized by MyAgency using Warp Performance -->';
} );
JavaScript Optimization
WARP_PERFORMANCE_exclude_from_minify:jsfilter
Exclude JavaScript files from minification by providing a partial URL, file name, or script handle keyword. Any script whose URL contains a listed string will be skipped.
$excludes(array) — Keyword strings. Default:[].
add_filter( 'WARP_PERFORMANCE_exclude_from_minify:js', function( $excludes ) {
// Exclude a specific library
$excludes[] = 'my-library.js';
// Exclude all scripts from a specific plugin
$excludes[] = 'my-plugin/assets/';
return $excludes;
} );
WARP_PERFORMANCE_exclude_from_defer:jsfilter
Exclude JavaScript files from the “Defer JS” feature. Any script whose URL contains a listed string keeps its original loading behavior.
$excludes(array) — Keyword strings. Populated from settings by default.
add_filter( 'WARP_PERFORMANCE_exclude_from_defer:js', function( $excludes ) {
$excludes[] = 'inline-critical.js';
return $excludes;
} );
WARP_PERFORMANCE_exclude_from_delay:jsfilter
Exclude JavaScript files from the “Delay JS” feature. Any script whose URL contains a listed string will execute normally instead of being delayed until user interaction.
$excludes(array) — Keyword strings. Populated from settings by default.
add_filter( 'WARP_PERFORMANCE_exclude_from_delay:js', function( $excludes ) {
// Never delay the payment gateway script
$excludes[] = 'stripe.js';
$excludes[] = 'paypal';
// Never delay a critical theme script
$excludes[] = 'theme-critical.js';
return $excludes;
} );
WARP_PERFORMANCE_js_delay_methodfilter
Overrides the configured Delay JS method for the current request.
$method(string) — One ofselected,all,idle,3rd-party. Default: config value.
add_filter( 'WARP_PERFORMANCE_js_delay_method', function( $method ) {
// Delay everything on landing pages only
return is_page_template( 'landing.php' ) ? 'all' : $method;
} );
WARP_PERFORMANCE_js_delay_interaction_onlyfilter
Scripts listed here are delayed until a genuine visitor interaction and are never released by the fallback timeout. Use it for third-party embeds — chat widgets, heavy trackers — that you do not want booting on their own during an automated page test.
$keywords(array) — Keyword strings matched against the script tag. Default: the list under Settings → JavaScript (empty by default).
add_filter( 'WARP_PERFORMANCE_js_delay_interaction_only', function( $keywords ) {
$keywords[] = 'tawk.to';
$keywords[] = 'intercom';
return $keywords;
} );
WARP_PERFORMANCE_js_delay_timeoutfilter
Sets the fallback timeout, in seconds, after which delayed scripts run on their own even if the visitor never interacts with the page. The same timeout also releases interaction-loaded videos.
$timeout(int) — Seconds before auto-execution. Default:10. Set to0to disable the fallback entirely, so delayed scripts wait for a genuine interaction and nothing else.
// Wait 5 seconds instead of 10
add_filter( 'WARP_PERFORMANCE_js_delay_timeout', function( $timeout ) {
return 5;
} );
// Never run delayed scripts without a real interaction
add_filter( 'WARP_PERFORMANCE_js_delay_timeout', '__return_zero' );
The value is in seconds. Passing 5000 here means 5000 seconds, not 5 seconds. Scripts listed under WARP_PERFORMANCE_js_delay_interaction_only ignore this timeout and always wait for a real interaction.
CSS Optimization
WARP_PERFORMANCE_exclude_from_minify:cssfilter
Exclude CSS files from minification by providing a partial URL, file name, or stylesheet handle keyword.
$excludes(array) — Keyword strings. Default:[].
add_filter( 'WARP_PERFORMANCE_exclude_from_minify:css', function( $excludes ) {
// Exclude a stylesheet that breaks when minified
$excludes[] = 'my-complex-grid.css';
$excludes[] = 'legacy-plugin/style.css';
return $excludes;
} );
WARP_PERFORMANCE_rucss_exclude_stylesheetsfilter
Stylesheets excluded from Remove Unused CSS. Excluded stylesheets keep loading normally instead of being replaced by the generated UsedCSS. Warp’s page-builder integrations (e.g., Bricks) use this internally.
$excludes(array) — Partial URLs or handles. Populated from settings by default.
add_filter( 'WARP_PERFORMANCE_rucss_exclude_stylesheets', function( $excludes ) {
$excludes[] = 'my-dynamic-theme.css';
return $excludes;
} );
Speculative Loading (Speculation Rules)
WARP_PERFORMANCE_speculation_modefilter
The speculative loading action injected into pages.
$mode(string) —prerender,prefetchorhybrid.
add_filter( 'WARP_PERFORMANCE_speculation_mode', function() {
return 'prefetch';
} );
WARP_PERFORMANCE_speculation_eagernessfilter
How aggressively the browser speculates. Default: moderate.
$eagerness(string) —conservative,moderateoreager.
add_filter( 'WARP_PERFORMANCE_speculation_eagerness', function() {
return 'conservative';
} );
WARP_PERFORMANCE_speculation_exclude_patternsfilter
URL patterns excluded from speculative loading (in addition to Warp’s built-in exclusions for wp-admin, cart, checkout, etc.).
$patterns(array) —href_matchespattern strings.
add_filter( 'WARP_PERFORMANCE_speculation_exclude_patterns', function( $patterns ) {
$patterns[] = '*/book-appointment/*';
return $patterns;
} );
WARP_PERFORMANCE_speculation_rulesfilter
Full control over the final Speculation Rules JSON structure before it is injected.
$rules(array) — The complete rules array.
add_filter( 'WARP_PERFORMANCE_speculation_rules', function( $rules ) {
// Inspect or replace the generated rules entirely
return $rules;
} );
Media
WARP_PERFORMANCE_youtube_placeholder_resolutionfilter
Sets the YouTube thumbnail resolution used for the click-to-play placeholder image.
$resolution(string) — YouTube thumbnail quality key. Default:hqdefault.
Available values (lowest to highest quality): default (120×90), mqdefault (320×180), hqdefault (480×360, default), sddefault (640×480), maxresdefault (1280×720, not available for all videos).
add_filter( 'WARP_PERFORMANCE_youtube_placeholder_resolution', function( $res ) {
return 'sddefault';
} );
WARP_PERFORMANCE_lqip_max_per_pagefilter
Maximum number of images per page that receive a low-quality image placeholder (LQIP). Default: 20.
add_filter( 'WARP_PERFORMANCE_lqip_max_per_page', function() {
return 10;
} );
WARP_PERFORMANCE_srcset_max_widthfilter
Caps the widest image the browser is allowed to pick from a srcset. Any candidate wider than this is dropped from the list, cutting page weight on image-heavy pages. Applies sitewide, to every visitor, because a CDN cannot vary its cached copy by device.
$width(int) — Maximum width in pixels.0disables the cap. Default: the “Maximum image width” setting (0unless you set one).
add_filter( 'WARP_PERFORMANCE_srcset_max_width', function() {
return 1600;
} );
WARP_PERFORMANCE_srcset_max_width_excludesfilter
Images whose markup contains one of these keywords keep their full srcset and ignore the width cap above.
$keywords(array) — Keyword strings. Default: the exclusion list beside the width setting.
add_filter( 'WARP_PERFORMANCE_srcset_max_width_excludes', function( $keywords ) {
$keywords[] = 'wp-image-hero';
$keywords[] = '/portfolio-prints/';
return $keywords;
} );
Self-hosted Third-party Assets
WARP_PERFORMANCE_selfhost_external_domainsfilter
The list of external CDN domains whose CSS/JS Warp downloads and serves locally when “Self-host third-party assets” is enabled. Defaults include jsDelivr, cdnjs, unpkg, Google Ajax and similar public CDNs.
$domains(array) — Hostnames eligible for self-hosting.
add_filter( 'WARP_PERFORMANCE_selfhost_external_domains', function( $domains ) {
$domains[] = 'cdn.my-vendor.com';
return $domains;
} );
WARP_PERFORMANCE_inline_url_ignore_hostsfilter
Hostnames ignored when Warp rewrites URLs found inside inline styles/scripts (namespace URLs like w3.org are ignored by default).
$hosts(array) — Hostnames to leave untouched.
add_filter( 'WARP_PERFORMANCE_inline_url_ignore_hosts', function( $hosts ) {
$hosts[] = 'schema.org';
return $hosts;
} );
WARP_PERFORMANCE_download_external_file:beforefilter
Filters the contents of a downloaded third-party file before Warp stores it locally. Warp uses this internally to self-host fonts referenced inside downloaded CSS.
$content(string) — The downloaded file body.$url(string) — The source URL.$extension(string) — The resolved file extension.
add_filter( 'WARP_PERFORMANCE_download_external_file:before', function( $content, $url, $extension ) {
if ( $extension === 'css' ) {
$content = str_replace( 'foo', 'bar', $content );
}
return $content;
}, 10, 3 );
Admin Access Control
WARP_PERFORMANCE_allowed_rolesfilter
Controls which additional user roles get cache-management access (purge and preload from the admin toolbar and cache endpoints). Administrators always have full access and cannot be removed via this filter. Roles granted here do not gain access to plugin settings.
$roles(array) — Role slugs with cache-management access. Default: the roles selected under Settings → Access Control (empty by default).
// Grant a custom role cache-management access
add_filter( 'WARP_PERFORMANCE_allowed_roles', function( $roles ) {
$roles[] = 'site_manager';
return $roles;
} );
// Revoke all non-admin access regardless of settings
add_filter( 'WARP_PERFORMANCE_allowed_roles', '__return_empty_array' );
Cloudflare — Query String Ignore List
WARP_PERFORMANCE_ignore_queriesfilter
When Cloudflare integration is active with “Ignore Query String” enabled, this filter controls which query parameters are included in the Cloudflare cache ignore rule.
$queries(array) — Query parameter names that Cloudflare should ignore when caching.
add_filter( 'WARP_PERFORMANCE_ignore_queries', function( $queries ) {
// Add your own tracking parameters to Cloudflare's ignore list
$queries[] = 'campaign';
$queries[] = 'affiliate_id';
return $queries;
} );
Redis Object Cache
Warp’s Redis object cache drop-in fires the ecosystem-standard actions on flush, so tooling built for other Redis object cache plugins keeps working.
redis_object_cache_flushaction
Fires after the entire object cache is flushed. Note: no WARP_PERFORMANCE_ prefix — this matches the ecosystem convention.
$result(bool) — Whether the flush succeeded.
add_action( 'redis_object_cache_flush', function( $result ) {
error_log( '[MyPlugin] Object cache flushed: ' . ( $result ? 'ok' : 'failed' ) );
} );
redis_object_cache_flush_groupaction
Fires after a single cache group is selectively flushed.
$group(string) — The flushed cache group.$pattern(string) — The Redis key pattern that was deleted.
add_action( 'redis_object_cache_flush_group', function( $group, $pattern ) {
error_log( '[MyPlugin] Flushed object cache group: ' . $group );
}, 10, 2 );
AI Assistant (MCP)
When the MCP server is enabled (Settings → AI Assistant), Warp exposes read tools and an opt-in update-settings tool to AI agents at /wp-json/warp-performance/mcp, authenticated with WordPress Application Passwords. These filters let you tighten what an agent can see and do. Credentials, access roles, header/footer code and the MCP toggles themselves are never readable or writable by agents, regardless of these filters.
WARP_PERFORMANCE_mcp_writable_keysfilter
The setting keys an AI agent may change through the update-settings MCP tool. Use it to restrict the default list further. The MCP flags (mcp_enabled, mcp_write_enabled) are stripped from the result unconditionally — an agent can never grant itself access.
$keys(array) — Writable setting keys. Default: all performance-tuning keys.
// Only let AI agents tune JS and CSS optimization — nothing else
add_filter( 'WARP_PERFORMANCE_mcp_writable_keys', function( $keys ) {
return array_filter( $keys, function( $key ) {
return strpos( $key, 'js_' ) === 0 || strpos( $key, 'css_' ) === 0;
} );
} );
WARP_PERFORMANCE_mcp_protected_keysfilter
Setting keys removed from every MCP read response. This filter is additive-only: you can protect more keys, but the built-in protected set (license key, API tokens, passwords) can never be exposed by returning a smaller list.
$keys(array) — Keys hidden from agents. Default: all credential keys.
add_filter( 'WARP_PERFORMANCE_mcp_protected_keys', function( $keys ) {
// Also hide the CDN URL from AI agents
$keys[] = 'cdn_url';
return $keys;
} );
WARP_PERFORMANCE_mcp_write_cooldownfilter
Minimum number of seconds between AI-initiated settings changes. Each accepted change purges the page cache and schedules a preload, so the cooldown protects against agent retry loops. Default: 10. Return 0 to disable.
add_filter( 'WARP_PERFORMANCE_mcp_write_cooldown', function() {
return 60;
} );
Config Change Events
WARP_PERFORMANCE_update_config:afteraction
Fires whenever the plugin configuration is saved (e.g., when a user toggles a setting in the dashboard, or an AI agent updates settings via MCP).
$new_config(array) — The updated configuration array. Always present.$old_config(array) — The previous configuration array. Only present when triggered by a config save; not passed when the action fires during a plugin version upgrade. Always set a default value of[]in your callback.
add_action( 'WARP_PERFORMANCE_update_config:after', function( $new_config, $old_config = [] ) {
// Detect when RUCSS is toggled on (only meaningful on user save, not upgrades)
if ( ! empty( $new_config['css_rucss'] ) && empty( $old_config['css_rucss'] ) ) {
WarpPerformance\Purge::purge_pages();
}
// Log all config changes in development
if ( defined( 'WP_DEBUG' ) && WP_DEBUG && ! empty( $old_config ) ) {
$changed = array_diff_assoc( $new_config, $old_config );
error_log( '[Warp] Config changed: ' . wp_json_encode( $changed ) );
}
}, 10, 2 );
WARP_PERFORMANCE_upgradedaction
Fires after the plugin is upgraded to a new version. Passes no parameters — use the WARP_PERFORMANCE_VERSION constant if you need the new version string.
add_action( 'WARP_PERFORMANCE_upgraded', function() {
// Run your own migration on upgrade
my_plugin_run_migration( WARP_PERFORMANCE_VERSION );
} );
Programmatic Purging (PHP)
You can call Warp’s purge methods directly from PHP without using hooks.
Purge a Single URL
WarpPerformance\Purge::purge_url( home_url( '/products/my-product/' ) );
Purge Multiple URLs
WarpPerformance\Purge::purge_urls( [
home_url( '/' ),
home_url( '/shop/' ),
home_url( '/products/my-product/' ),
] );
Purge All Cached Pages
WarpPerformance\Purge::purge_pages();
Full Cache Reset
Purges pages, OPcache, and object cache, and also triggers Cloudflare/Bunny CDN purge if configured.
WarpPerformance\Purge::purge_everything();
Example: Purge on Custom Plugin Event
add_action( 'my_plugin_product_updated', function( $product_id ) {
$product_url = get_permalink( $product_id );
if ( $product_url ) {
WarpPerformance\Purge::purge_url( $product_url );
}
} );
Example: Purge on ACF Options Page Save
add_action( 'acf/save_post', function( $post_id ) {
if ( $post_id === 'options' ) {
WarpPerformance\Purge::purge_pages();
}
} );
Image Optimization
These filters tune the local image optimizer. They only apply while image optimization is enabled, which is off by default.
WARP_PERFORMANCE_image_optimizer_excludesfilter
Keyword exclusions for the optimizer, matched against each file’s path relative to the uploads folder. A matching image is never converted or compressed.
$keywords(array) — Keyword strings. Default: the keyword list under Settings → Images (also editable from the Media Library).
add_filter( 'WARP_PERFORMANCE_image_optimizer_excludes', function( $keywords ) {
$keywords[] = '2019/'; // leave an entire year alone
$keywords[] = 'client-logos';
return $keywords;
} );
WARP_PERFORMANCE_image_optimizer_offloadersfilter
The list of detected media-offload plugins. While this list is non-empty, in-place compression is disabled and remote attachments are skipped, because Warp cannot safely rewrite files it does not own. Warp detects WP Offload Media, S3 Uploads, WP-Stateless, Media Cloud, and an uploads directory that is not local.
$offloaders(array) — Human-readable names of detected offloaders. Return an empty array to override detection, or append your own.
// Tell Warp about an offloader it does not know
add_filter( 'WARP_PERFORMANCE_image_optimizer_offloaders', function( $found ) {
if ( class_exists( 'My_Custom_Offloader' ) ) {
$found[] = 'My Custom Offloader';
}
return $found;
} );
Overriding this to an empty array while an offloader really is active will let Warp write to files the offloader manages. Only do it if you are certain your uploads are local.
WARP_PERFORMANCE_image_optimizer_skip_attachmentfilter
Skip a specific attachment entirely. Nothing is converted, compressed or rewritten for it.
$skip(bool) — Whether to skip this attachment. Default:false.$attachment_id(int) — The attachment being considered.
add_filter( 'WARP_PERFORMANCE_image_optimizer_skip_attachment', function( $skip, $attachment_id ) {
$file = get_attached_file( $attachment_id );
if ( $file && strpos( $file, '/originals/' ) !== false ) {
return true;
}
return $skip;
}, 10, 2 );
WARP_PERFORMANCE_image_optimizer_min_saving_bytesfilter
How much smaller the converted copy must be before it is kept. Anything saving less than this is discarded, so you do not store a second file for a negligible gain.
$bytes(int) — Minimum saving in bytes. Default:5120(5 KB).
add_filter( 'WARP_PERFORMANCE_image_optimizer_min_saving_bytes', function() {
return 1024; // keep conversions that save at least 1 KB
} );
WARP_PERFORMANCE_image_optimizer_min_bytesfilter
Source images smaller than this are never converted. Tiny files rarely compress usefully and cost a request either way.
$bytes(int) — Minimum source size in bytes. Default:4096(4 KB).
WARP_PERFORMANCE_image_optimizer_max_bytesfilter
Source images larger than this are skipped, to protect against a single huge file exhausting memory or execution time.
$bytes(int) — Maximum source size in bytes. Default:26214400(25 MB).
add_filter( 'WARP_PERFORMANCE_image_optimizer_max_bytes', function() {
return 50 * MB_IN_BYTES;
} );
WARP_PERFORMANCE_image_optimizer_budgetfilter
Seconds each optimizer worker run may spend before stopping and resuming on the next run. Defaults to 60% of the server max_execution_time. Values below 5 are ignored.
$seconds(int) — Time budget per run.
WARP_PERFORMANCE_image_optimizer_delayfilter
Pause between individual images, in milliseconds, to reduce sustained CPU load on shared hosting. Capped at 2000 ms.
$milliseconds(int) — Delay between images. Default:0.
add_filter( 'WARP_PERFORMANCE_image_optimizer_delay', function() {
return 250; // gentler on a shared host
} );
WARP_PERFORMANCE_image_optimizer_preload_after_bulkfilter
Whether finishing a bulk optimization should purge and preload the whole cache. Off by default, because on a large site that is a lot of work for a change that only affects image URLs.
$preload(bool) — Whether to purge and preload. Default:false.
Font Preloading
WARP_PERFORMANCE_auto_preload_fonts_budgetfilter
Total byte budget for automatically preloaded fonts. Once the budget is used up no further fonts are preloaded, so a large font set cannot push your LCP image down the queue.
$bytes(int) — Preload budget in bytes. Default:153600(150 KB).
add_filter( 'WARP_PERFORMANCE_auto_preload_fonts_budget', function() {
return 80 * 1024;
} );
WARP_PERFORMANCE_auto_preload_fonts_excludesfilter
Substrings matched against the font URL. Any match is never auto-preloaded.
$excludes(array) — List of substrings. Default:[].
add_filter( 'WARP_PERFORMANCE_auto_preload_fonts_excludes', function( $excludes ) {
$excludes[] = 'icons';
return $excludes;
} );
WARP_PERFORMANCE_auto_preload_fonts_formatsfilter
Font formats eligible for automatic preloading.
$formats(array) — File extensions without the dot. Default:['woff2'].
Delay JavaScript Safety Net
While scripts are delayed, Warp injects a small stylesheet that stops a theme or builder from leaving the page blank when the script that would reveal its content has not run yet.
WARP_PERFORMANCE_js_delay_hold_visible_cssfilter
CSS rules injected while scripts are still delayed. Return an array of CSS rule strings.
$rules(array) — CSS rules as strings. Default: the generic visibility guard.
add_filter( 'WARP_PERFORMANCE_js_delay_hold_visible_css', function( $rules ) {
$rules[] = 'html:not(.warp-js-ready) .my-slider{opacity:1!important}';
return $rules;
} );
WARP_PERFORMANCE_js_delay_hold_generic_guardfilter
Return false to drop the built-in generic guard entirely and supply your own rules instead. Only do this if the default rules conflict with your theme.
$enabled(bool) — Whether to emit the built-in guard. Default:true.
WARP_PERFORMANCE_js_delay_hold_release_delayfilter
Milliseconds to wait after delayed scripts run before releasing the hold, giving a builder script time to take over the elements it animates.
$milliseconds(int) — Release delay. Default:300.
WARP_PERFORMANCE_js_delay_anim_skip_selectorsfilter
Selectors whose entrance animations should not replay once delayed scripts run. Used for content that was already on screen before the scripts loaded.
$selectors(array) — CSS selectors. Default:[](page builder integrations add their own).
Other Tuning Filters
WARP_PERFORMANCE_css_rucss_methodfilter
Overrides how deferred stylesheets are loaded when Remove Unused CSS is on, without changing the saved setting.
$method(string) — Default: thecss_rucss_methodsetting.
WARP_PERFORMANCE_cloud_down_ttlfilter
How long Warp waits before retrying the cloud optimizer after consecutive failures. The back-off escalates with the failure count and never drops below one minute.
$ttl(int) — Seconds before the next attempt.$failures(int) — Consecutive failure count.
WARP_PERFORMANCE_cloud_resubmit_hourly_budgetfilter
How many pages Warp may send for optimization again in one hour after finding the cloud no longer holds their result. Each page is also limited to one attempt per hour. Set to 0 to turn automatic recovery off.
$budget(int) — Pages per hour. Default:60.
WARP_PERFORMANCE_cloud_memo_gc_budgetfilter
How many stale helper files the hourly cleanup may delete in a single run. Lower it on hosts with slow disks.
$budget(int) — Files per run. Default:25000.
WARP_PERFORMANCE_excluded_cache_manager_rolesfilter
Roles that can never be granted cache-manager access, regardless of the dashboard setting.
$roles(array) — Role slugs. Default:['subscriber', 'customer'].
WARP_PERFORMANCE_mcp_rate_limitsfilter
Requests allowed per tier, per user, per hour.
$limits(array) — Default:['read' => 120, 'write' => 20].
add_filter( 'WARP_PERFORMANCE_mcp_rate_limits', function( $limits ) {
$limits['read'] = 300;
return $limits;
} );
WARP_PERFORMANCE_mcp_allow_insecurefilter
Allows MCP requests over plain HTTP. Intended for local development only. Leave this off on any public site, because Application Password credentials would travel unencrypted.
$allow(bool) — Whether to permit non-HTTPS MCP requests. Default:false.
WARP_PERFORMANCE_cloud_fail_cooldownfilter
How long a recorded cloud failure pauses further attempts for that page. A failure is treated as a pause, not a verdict — once the cooldown passes, the page is submitted again.
$cooldown(int) — Seconds to wait. Default:3600(1 hour).$fail(array) — The recorded failure, including its reason and timestamp.
WARP_PERFORMANCE_cloud_max_status_retriesfilter
How many times Warp asks the cloud about one pending optimization before giving up on it. After this, the request is abandoned and not retried for 24 hours, rather than being polled indefinitely.
$max_retries(int) — Status checks per request. Default:22.
WARP_PERFORMANCE_max_optimize_attemptsfilter
How many failed optimization attempts a page may accumulate before Warp stops holding it back and caches it without Used CSS. This is what stops a page that cannot be optimized from staying out of your CDN forever.
$max_attempts(int) — Attempts before giving up. Default:5.
WARP_PERFORMANCE_preload_max_concurrencyfilter
The total number of pages the preloader may fetch at once, across all workers. This is a ceiling on the whole crawl, not a per-worker figure, so raising it raises the load on PHP directly.
$ceiling(int) — Concurrent preload requests. Default:10. Minimum2.
WARP_PERFORMANCE_bunny_url_purge_max_attemptsfilter
How many times a single URL may fail to purge at Bunny before it is dropped from the queue and logged once. Without this, an unpurgeable URL would be retried every 30 seconds forever.
$max_attempts(int) — Failed attempts before dropping the URL. Default:5.0retries indefinitely.
WARP_PERFORMANCE_reactivation_purge_afterfilter
How long the plugin may stay deactivated before its cached pages are considered stale and cleared on reactivation. A plugin update deactivates and reactivates within seconds, so the default keeps the cache through an update while still clearing it after a genuine period offline.
$seconds(int) — Grace period in seconds. Default:900(15 minutes).0always purges; a negative value never does.
// Never clear the page cache on reactivation
add_filter( 'WARP_PERFORMANCE_reactivation_purge_after', function() {
return -1;
} );
Full Hook Index
Filters
| Filter | Description | Default |
|---|---|---|
WARP_PERFORMANCE_is_cacheable | Final cache decision for current page | true |
WARP_PERFORMANCE_request_uri | Modify request URI used for cache lookup | $_SERVER['REQUEST_URI'] |
WARP_PERFORMANCE_cache_file_path | Sub-path a page is cached under, inside the cache directory | URL path |
WARP_PERFORMANCE_cache_file_name | Modify the cache file name/hash | Role + query composite |
WARP_PERFORMANCE_cache_include_queries | Query params to include in cache key | lang, currency, … |
WARP_PERFORMANCE_cache_allowed_hosts | Hostnames served from cache | Site host |
WARP_PERFORMANCE_cache_mobile | Treat request as mobile | Config value |
WARP_PERFORMANCE_cache_admins | Cache pages for admin users | false |
WARP_PERFORMANCE_cache_excluded_roles | Roles excluded from cache | [] |
WARP_PERFORMANCE_brotli_level | Brotli compression level (1–11) | 9 |
WARP_PERFORMANCE_auto_purge_urls | URLs purged on post save | Post + archives |
WARP_PERFORMANCE_auto_preload_urls | URLs preloaded after auto-purge | Purged URLs |
WARP_PERFORMANCE_is_url_preloadable | Allow/deny preload per URL | true |
WARP_PERFORMANCE_excluded_post_types | Post types excluded from cache/preload | Builder templates |
WARP_PERFORMANCE_preload_recent_posts_count | Recent posts prioritized in preload | 10 |
WARP_PERFORMANCE_preload_terms_cap | Max term archives queued for preload | 5000 |
WARP_PERFORMANCE_homepage_link_excludes | Path fragments skipped in homepage link collection | /author/, /feed, … |
WARP_PERFORMANCE_optimization:after | Final HTML after all optimizations | Processed HTML |
WARP_PERFORMANCE_footprint | HTML comment appended to cached pages | Warp comment + timestamp |
WARP_PERFORMANCE_exclude_from_minify:js | Scripts excluded from JS minification | [] |
WARP_PERFORMANCE_exclude_from_defer:js | Scripts excluded from JS defer | Config value |
WARP_PERFORMANCE_exclude_from_delay:js | Scripts excluded from JS delay | Config value |
WARP_PERFORMANCE_js_delay_interaction_only | Scripts that wait for a real interaction and ignore the fallback timeout | Config value |
WARP_PERFORMANCE_js_delay_method | Delay JS method override | Config value |
WARP_PERFORMANCE_js_delay_timeout | Fallback timeout for delayed scripts, in seconds (0 disables) | 10 |
WARP_PERFORMANCE_exclude_from_minify:css | Stylesheets excluded from CSS minification | [] |
WARP_PERFORMANCE_rucss_exclude_stylesheets | Stylesheets excluded from Remove Unused CSS | Config value |
WARP_PERFORMANCE_speculation_mode | Speculative loading action | prerender |
WARP_PERFORMANCE_speculation_eagerness | Speculative loading eagerness | moderate |
WARP_PERFORMANCE_speculation_exclude_patterns | URL patterns excluded from speculation | Built-in list |
WARP_PERFORMANCE_speculation_rules | Final Speculation Rules JSON | Generated rules |
WARP_PERFORMANCE_youtube_placeholder_resolution | YouTube thumbnail resolution | hqdefault |
WARP_PERFORMANCE_lqip_max_per_page | Max LQIP placeholders per page | 20 |
WARP_PERFORMANCE_srcset_max_width | Widest image a browser may pick from a srcset | Config value (0 = off) |
WARP_PERFORMANCE_srcset_max_width_excludes | Images exempt from the width cap | Config value |
WARP_PERFORMANCE_selfhost_external_domains | CDN domains eligible for self-hosting | Public CDN list |
WARP_PERFORMANCE_inline_url_ignore_hosts | Hosts ignored in inline URL rewriting | w3.org, … |
WARP_PERFORMANCE_download_external_file:before | Downloaded third-party file contents | File body |
WARP_PERFORMANCE_allowed_roles | Roles with cache-management access | Access Control setting |
WARP_PERFORMANCE_ignore_queries | Query params for Cloudflare ignore rule | Default ignore list |
WARP_PERFORMANCE_mcp_writable_keys | Settings writable by AI agents via MCP | Performance keys |
WARP_PERFORMANCE_mcp_protected_keys | Settings hidden from MCP reads (additive-only) | Credential keys |
WARP_PERFORMANCE_mcp_write_cooldown | Seconds between AI settings changes | 10 |
WARP_PERFORMANCE_htaccess_rules | Generated .htaccess rules string | Generated rules |
WARP_PERFORMANCE_advanced_cache | Generated advanced-cache.php drop-in source | Generated source |
WARP_PERFORMANCE_link_header_htaccess | Early Hints Link header .htaccess block | Generated rules |
WARP_PERFORMANCE_image_optimizer_skip_attachment | Skip one attachment entirely | false |
WARP_PERFORMANCE_image_optimizer_excludes | Keyword exclusions for the image optimizer | Config value |
WARP_PERFORMANCE_image_optimizer_offloaders | Detected media-offload plugins | Auto-detected |
WARP_PERFORMANCE_image_optimizer_min_saving_bytes | Minimum saving before a copy is kept | 5 KB |
WARP_PERFORMANCE_image_optimizer_min_bytes | Smallest source image to convert | 4 KB |
WARP_PERFORMANCE_image_optimizer_max_bytes | Largest source image to convert | 25 MB |
WARP_PERFORMANCE_image_optimizer_preload_after_bulk | Purge and preload after bulk optimize | false |
WARP_PERFORMANCE_auto_preload_fonts_budget | Byte budget for auto font preloads | 150 KB |
WARP_PERFORMANCE_auto_preload_fonts_excludes | Font URL substrings never preloaded | [] |
WARP_PERFORMANCE_auto_preload_fonts_formats | Formats eligible for font preload | [woff2] |
WARP_PERFORMANCE_js_delay_hold_visible_css | CSS applied while scripts are delayed | Generic guard |
WARP_PERFORMANCE_js_delay_hold_generic_guard | Emit the built-in visibility guard | true |
WARP_PERFORMANCE_js_delay_anim_skip_selectors | Selectors whose animations do not replay | [] |
WARP_PERFORMANCE_css_rucss_method | Override deferred stylesheet loading method | Config value |
WARP_PERFORMANCE_excluded_cache_manager_roles | Roles never granted cache-manager access | subscriber, customer |
WARP_PERFORMANCE_mcp_rate_limits | MCP requests per tier per user per hour | read 120, write 20 |
WARP_PERFORMANCE_mcp_allow_insecure | Allow MCP over plain HTTP | false |
WARP_PERFORMANCE_max_optimize_attempts | Failed optimizations before a page is cached without Used CSS | 5 |
WARP_PERFORMANCE_reactivation_purge_after | Deactivation grace period before the cache is cleared | 900 (15 min) |
Advanced Tuning Filters
Internal timing/batching knobs — safe to leave at defaults; change only when diagnosing large-site behavior.
| Filter | Description | Default |
|---|---|---|
WARP_PERFORMANCE_auto_preload_fonts_limit | Max fonts auto-preloaded | Built-in |
WARP_PERFORMANCE_preload_populate_batch | URLs inserted into queue per batch | Built-in |
WARP_PERFORMANCE_preload_sweep_rows_per_run | Manifest rows verified per sweep run | Built-in |
WARP_PERFORMANCE_preload_sweep_max_retries | Max verification retries per URL | Built-in |
WARP_PERFORMANCE_generation_lock_ttl | Page generation lock TTL (s) | Built-in |
WARP_PERFORMANCE_queue_retry_cooldown | Queue retry cooldown (s) | Built-in |
warp_queue_max_workers | Parallel preload queue workers | Built-in |
warp_queue_lock_timeout | Queue worker lock timeout (s) | Built-in |
WARP_PERFORMANCE_cloud_initial_check_delay | First cloud status check delay (s) | Built-in |
WARP_PERFORMANCE_cloud_async_retry_delay | Cloud async retry delay (s) | Built-in |
WARP_PERFORMANCE_cloud_preload_check_delay | Cloud check delay during preload (s) | Built-in |
WARP_PERFORMANCE_cloud_throttled_check_delay | Cloud check delay when throttled (s) | Built-in |
WARP_PERFORMANCE_cloud_status_check_slots | Concurrent cloud status check slots | Built-in |
WARP_PERFORMANCE_cloud_status_check_slot_ttl | Cloud status check slot TTL (s) | Built-in |
WARP_PERFORMANCE_cloud_status_check_timeout | Cloud status check HTTP timeout (s) | Built-in |
WARP_PERFORMANCE_image_optimizer_budget | Seconds per optimizer worker run | 60% of max_execution_time |
WARP_PERFORMANCE_image_optimizer_delay | Pause between images (ms) | 0 |
WARP_PERFORMANCE_js_delay_hold_release_delay | Delay before releasing the hold (ms) | 300 |
WARP_PERFORMANCE_cloud_down_ttl | Back-off before retrying the cloud | Escalating |
WARP_PERFORMANCE_cloud_resubmit_hourly_budget | Pages re-sent for optimization per hour | 60 |
WARP_PERFORMANCE_cloud_memo_gc_budget | Stale helper files deleted per cleanup run | 25000 |
WARP_PERFORMANCE_cloud_fail_cooldown | Pause after a recorded cloud failure | 3600 (1 hour) |
WARP_PERFORMANCE_cloud_max_status_retries | Status checks before abandoning one request | 22 |
WARP_PERFORMANCE_preload_max_concurrency | Total pages preloaded at once, all workers | 10 |
WARP_PERFORMANCE_bunny_url_purge_max_attempts | Failed Bunny purges before a URL is dropped | 5 |
Actions
| Action | Description | Parameters |
|---|---|---|
WARP_PERFORMANCE_purge_url:before | Before a single URL is purged | $url |
WARP_PERFORMANCE_purge_url:after | After a single URL is purged | $url |
WARP_PERFORMANCE_purge_urls:before | Before a batch of URLs is purged | $urls |
WARP_PERFORMANCE_purge_urls:after | After a batch of URLs is purged | $urls |
WARP_PERFORMANCE_purge_pages:before | Before all pages are purged | — |
WARP_PERFORMANCE_purge_pages:after | After all pages are purged | — |
WARP_PERFORMANCE_purge_everything:before | Before full cache reset | — |
WARP_PERFORMANCE_purge_everything:after | After full cache reset | — |
WARP_PERFORMANCE_purge_everything | After full cache reset (unsuffixed alias) | — |
WARP_PERFORMANCE_preloaded_urls | After a batch of URLs is preloaded | $urls |
WARP_PERFORMANCE_queue_drained | Preload queue finished all jobs | — |
WARP_PERFORMANCE_update_config:after | After settings are saved | $new_config, $old_config (optional) |
WARP_PERFORMANCE_upgraded | After plugin version upgrade | — |
redis_object_cache_flush | After object cache flush (drop-in) | $result |
redis_object_cache_flush_group | After selective group flush (drop-in) | $group, $pattern |
Constants
| Constant | Effect |
|---|---|
WARP_BYPASS_CACHE | Set to true to bypass caching for all requests |
WARP_PERFORMANCE_CACHE_DIR | Path to the cache directory (read-only) |
WARP_PERFORMANCE_PLUGIN_URL | URL to the plugin directory (read-only) |