WordPress flush_rewrite_rules Example: Refresh Routes Without a Performance Hit
How to refresh WordPress rewrite rules safely after route changes without turning an expensive setup task into runtime overhead.
Published
May 8, 2026
Reading Time
2 min read
Updated
May 8, 2026

Implementation Notes
Extension points, code paths, and implementation choices that should survive contact with production.
Best For
WordPress developers, agencies, and technical teams building custom plugin or theme functionality with cleaner operational defaults.
Primary Topics
Editorial Focus
Build Pattern: Extension points, code paths, and implementation choices that should survive contact with production. Updated on May 8, 2026.
Full Report
Last reviewed: May 8, 2026
Few WordPress helpers are misused as often as flush_rewrite_rules(). Developers add a custom post type, endpoint, or query var, see routing fail once, and then start flushing rewrites on every page load. That works in development and creates unnecessary overhead in production. The WordPress code reference is explicit: rewrite flushing is expensive and should only run when necessary.
This guide shows how to refresh rewrite rules safely without turning an occasional setup task into a recurring performance hit.
Flush only after the rewrite structures are registered
<?php
register_activation_hook( __FILE__, 'vulnwp_mark_rewrite_flush_needed' );
function vulnwp_mark_rewrite_flush_needed() {
update_option( 'vulnwp_needs_rewrite_flush', 1 );
}
add_action( 'init', 'vulnwp_register_routes' );
function vulnwp_register_routes() {
add_rewrite_rule( '^control-ledger/?$', 'index.php?vulnwp_control_ledger=1', 'top' );
if ( get_option( 'vulnwp_needs_rewrite_flush' ) ) {
flush_rewrite_rules( false );
update_option( 'vulnwp_needs_rewrite_flush', 0 );
}
}
The critical detail is timing. The custom rule must already be registered before the flush runs, otherwise WordPress regenerates the ruleset without the route you actually need.
Prefer a soft flush unless you intentionally need file writes
flush_rewrite_rules( false ) refreshes the stored rules without forcing a hard write to .htaccess. That is often enough for plugin-owned routes and avoids broader filesystem side effects when they are not required.
Never put rewrite flushing on normal request paths
This function does not belong in a regular front-end render, AJAX handler, REST callback, or admin page load. If the route model changes frequently enough that code wants to flush often, the design usually needs a better registration strategy instead.
Common mistakes
- Flushing on every request. This is the classic production bug.
- Flushing before the route is registered. The expensive operation then solves nothing.
- Using a hard flush by default. File writes should be deliberate, not habitual.
- Treating rewrite refresh as runtime business logic. It is a setup and lifecycle task.
Production checklist
- Register the custom route before any flush occurs.
- Trigger the flush from activation or a one-time upgrade path.
- Use a soft flush when database-level regeneration is enough.
- Keep rewrite refresh logic out of normal request handling.
- Retest the route after deployment and permalink changes.
Related reading
Pair this with the add_rewrite_endpoint guide when the route is endpoint-driven, and with the rewrite rules article when you need the lower-level rule mechanics.


