According to the Codex:

[...] This function can be extremely costly in terms of performance. It should be used as sparingly as possible - such as during activation or deactivation of plugins or themes. Every attempt should be made to avoid using it in hooks that execute on each page load, such as init.

Ok, so, I know it shouldn't be used in every page load and I'm not, but I still need a very conditional rewrite rule on this project. I have these 2 url structures:

 - example.com/products/tables/fancy-computer-table //This is a product url, here I expect the normal behavior from wp.

 - example.com/products/tables/office //This should be some kind of a filter, where the site gets all the tables related to the office department. Note how both URL structure matches.

To make it work, I narrowed it down to these very specific URLs, using some regex. If matched, I'll run 2 queries to verify if the url I'm in is for the filter I want that rule to apply, or if it's a product url. In the latter, I want wordpress to behave normally. But I have to flush the rules either way, whether it's a product or it's the category and the filter, so that both pages work properly and dinamically.

I do all this to narrow down the use of this function to the least possible, but the Codex doesn't really tell me how bad it does affect the performance, or why. I'm passing the parameter on that function as false by the way, so it doesn't rewrite my htaccess file, but I'm not sure where that rewrite rule option is stored, if it's on the memory somewhere, or on the database, wish they would provide some clarification on that.

Thanks in advance for reading this question. Any pointers are appreciated here, even if you want to point me to some other way of doing this. :)

EDIT: Posting some code here so you guys can actually understand what I mean and let me know if this is really a bad practice or not... maybe a suggestion on how to do it better.

<?php function custom_rewrite_products()
// regex to match either "products/tables/fancy-computer-table" or "products/tables/office"
preg_match('#products\/([^\/]+)\/([^\/]+)\/?#', $_SERVER['REQUEST_URI'], $url_matches);
if(is_array($url_matches)) {
    $query_category = new WP_Query('category_name='.$url_matches[1]);

    $args = array(
        'post_type' => 'filters',
        'name' => $url_matches[2]
    $query_post = new WP_Query($args);

    if($query_category->have_posts() && $query_post->have_posts()) {
        $category_ID = '';
        $filter = '';

        $category_ID = '' . $query_category->query_vars['cat'] . '';
        $filter = '' . $query_post->query_vars['name'] . '';
        $string = "index.php?cat={$category_ID}&filter={$filter}";
        add_rewrite_rule('products/([^/]+)/([^/]+)/?$', $string, 'top');

    global $wp_rewrite;
    //Call flush_rules() as a method of the $wp_rewrite object
 add_action('init', 'custom_rewrite_products');

I still don't understand why, but the flush is needed here, so the $category_ID and $filter variables actually get passed to the rewrite rules. If I take it out, the rewrite just goes to the index page, the place where the values should be are empty. In case you're wondering, I created the filters on a custom post type and they are related to each post by using a custom field, since they're like four or five and they're present on every category on this project. As you can see, I already have a category/subcategory structure and I didn't find it smart to create these filters once again by hand inside each main category.

  • If you are going to parse the URLs by yourself, as you show in your code, then there i no need to use the wordpress rewrite rules API. Feb 4, 2015 at 14:26
  • 1
    You're doing your request parsing in the wrong place. Add a single rewrite rule to capture both cases, and then do your parsing and query modification when those requests happen. See this question/answer that handles a similar situation.
    – Milo
    Feb 4, 2015 at 18:05

1 Answer 1


It sounds like you misunderstand how to add rewrite rules as your structure is relatively common and should not require flushing the rules on every page load.

The impact depends on your set of rewrite rules, and the codex is somewhat outdated and I don't think it is as bad as it used to be several versions ago, but still it is updating an option with a possibility that it will be written to the DB. Your site might actually survive a write to the DB on every page load (some stats plugins used to do it) but it is totally not scalable and your site will crush once it get traffic.

  • Even though the flush rules are not running on every page load, that's my concern, that once the site gets some traffic, it might have some trouble. I suspect I did something wrong on my structure to start with, but I'm not really sure... I'd appreciate if you could check the edit I just did on the question and comment on it. Thank you very much :) Feb 4, 2015 at 14:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.