How Bots Killed My WooCommerce Site Until I Automated WP Rocket Filter Caching


Last month, my client’s WooCommerce store went down. Not from a DDoS attack, not from bad code, but from Google and AI crawlers doing their job a little too enthusiastically.

The culprit? Uncached WooCommerce filter pages being hammered by bots, each request hitting the database directly. The solution? A simple WordPress plugin that took me an afternoon to write and has since saved multiple sites from the same fate.



The Day the Bots Came

It started innocently enough. Server response times began creeping up. Then came the alerts: CPU usage at 90%, memory exhausted, MySQL connections maxed out.

Looking at the access logs told the whole story:

Googlebot: GET /shop/?filter_color=red&min_price=50
BingBot: GET /shop/?filter_size=large&filter_material=cotton
GPTBot: GET /shop/?filter_brand=nike&max_price=200&rating_filter=4
ClaudeBot: GET /shop/?filter_color=blue&filter_size=medium&orderby=price
Enter fullscreen mode

Exit fullscreen mode

Hundreds of requests per minute, each with different filter combinations. Each one bypassing the cache. Each one running complex database queries.



Why WooCommerce Filters Break Under Load

WooCommerce uses URL parameters for product filtering. When a user (or bot) visits /shop/?filter_color=red, WooCommerce:

  1. Parses the filter parameters
  2. Builds complex SQL queries with JOINs across multiple tables
  3. Calculates product counts for each filter option
  4. Generates the filtered product list
  5. Renders the entire page

Without caching, this happens for EVERY request. Now multiply that by hundreds of bot requests per minute, each with different parameter combinations.



The WP Rocket Cache Gotcha

WP Rocket is fantastic at caching, but it has a security feature: by default, it ignores URLs with query parameters. This prevents accidentally caching user-specific content like cart pages or search results.

You can whitelist specific parameters in WP Rocket’s cache_query_strings setting, but here’s what that looks like for a typical WooCommerce store:

filter_color
query_type_color
filter_size
query_type_size
filter_material
query_type_material
filter_brand
query_type_brand
min_price
max_price
rating_filter
orderby
product_cat
product_tag
per_page
columns
sort
Enter fullscreen mode

Exit fullscreen mode

And that’s just the beginning. Every product attribute needs two entries (filter and query_type). Miss one? That parameter won’t be cached.



Manual Configuration: A Losing Battle

I started adding these manually. After 30 minutes of copying and pasting, I realized:

  • The client had 24 product attributes
  • They regularly added new ones for seasonal products
  • Other sites had the same problem
  • I was solving the symptom, not the problem

There had to be a better way.



Building the Solution

The solution was obvious: automate the entire process. The plugin needed to:

  1. Detect all WooCommerce attributes automatically
  2. Generate the correct filter parameters
  3. Update WP Rocket settings without breaking existing configurations
  4. Stay updated when attributes change

Here’s the core logic that makes it work:

public function get_woocommerce_filters() {
    $filters = array();
    $attribute_taxonomies = wc_get_attribute_taxonomies();

    // Generate filter parameters for each attribute
    foreach ( $attribute_taxonomies as $attribute ) {
        $filters[] = 'filter_' . $attribute->attribute_name;
        $filters[] = 'query_type_' . $attribute->attribute_name;
    }

    // Add standard WooCommerce filters
    $filters[] = 'min_price';
    $filters[] = 'max_price';
    $filters[] = 'rating_filter';
    $filters[] = 'orderby';
    $filters[] = 'product_cat';
    $filters[] = 'product_tag';
    $filters[] = 'per_page';
    $filters[] = 'columns';
    $filters[] = 'sort';

    return array_unique( $filters );
}
Enter fullscreen mode

Exit fullscreen mode



The Smart Update System

The trickiest part was updating WP Rocket settings without destroying manual customizations. The solution: marker comments.

private $filter_start_marker = '# filter_start';
private $filter_end_marker = '# filter_end';

public function update_filters() {
    $option = get_option( 'wp_rocket_settings' );
    $existing_strings = $option['cache_query_strings'];
    $new_filters = $this->get_woocommerce_filters();

    // Find our markers
    $start_index = array_search( $this->filter_start_marker, $existing_strings );
    $end_index = array_search( $this->filter_end_marker, $existing_strings );

    if ( $start_index !== false && $end_index !== false ) {
        // Preserve everything outside our markers
        $before = array_slice( $existing_strings, 0, $start_index );
        $after = array_slice( $existing_strings, $end_index + 1 );

        // Rebuild with updated filters
        $option['cache_query_strings'] = array_merge(
            $before,
            array( $this->filter_start_marker ),
            $new_filters,
            array( $this->filter_end_marker ),
            $after
        );
    }

    update_option( 'wp_rocket_settings', $option );
    rocket_clean_domain(); // Clear cache
}
Enter fullscreen mode

Exit fullscreen mode

This approach means:

  • Manual entries outside the markers are preserved
  • Automatic filters stay organized between markers
  • Updates don’t break existing configurations



Real-World Results

After deploying the plugin:

Before:

  • Server load average: 8.2 (on a 2-core server)
  • Average response time: 3.8 seconds
  • MySQL connections: 95% utilized
  • Monthly hosting cost: Considering upgrade

After:

  • Server load average: 0.6
  • Average response time: 0.4 seconds
  • MySQL connections: 15% utilized
  • Monthly hosting cost: Stayed on same plan

The bot traffic didn’t decrease – it just stopped killing the server. Filtered pages were now served from cache, turning database-heavy requests into simple file reads.



Automatic Updates: Set and Forget

The plugin hooks into WooCommerce attribute events:

add_action( 'woocommerce_attribute_added', array( $this, 'update_filters' ) );
add_action( 'woocommerce_attribute_updated', array( $this, 'update_filters' ) );
add_action( 'woocommerce_attribute_deleted', array( $this, 'update_filters' ) );
Enter fullscreen mode

Exit fullscreen mode

Add a new “Material” attribute? The filters update automatically. Delete an old seasonal attribute? Cleaned up automatically. No manual intervention needed.



Performance Impact: Basically Zero

The plugin is intentionally minimal:

  • No frontend processing: Only runs in admin and on attribute changes
  • No database queries: Reads existing WP options
  • No admin menus: Completely invisible once activated
  • No scheduled tasks: Event-driven updates only

Total plugin size: ~150 lines of code.



Open Source Release

I’ve released this as open source because every WooCommerce + WP Rocket user faces this problem. The plugin is:

  • Free to use and modify
  • GPL v2 licensed

GitHub Repository: https://github.com/trueqap/wp-rocket-woo-filters-cache



Installation in 30 Seconds

  1. Download from GitHub
  2. Upload to /wp-content/plugins/
  3. Activate
  4. Done – seriously, that’s it

The plugin immediately scans your attributes and updates WP Rocket settings. No configuration needed.



The Bigger Picture

This isn’t just about WooCommerce or WP Rocket. It’s about recognizing when manual processes become bottlenecks and having the confidence to automate them.

The hours I spent building this plugin have been repaid many times over in:

  • Support tickets avoided
  • Server upgrades prevented
  • Client sites staying online
  • My own sanity preserved

If you’re managing WooCommerce sites with WP Rocket, you need this. If you’re seeing high server loads from bot traffic, you need this. If you’re manually managing cache settings, you definitely need this.


Have you dealt with similar bot traffic issues? What’s your approach to handling aggressive crawlers? Let me know in the comments!

If this helped you, give the GitHub repo a star and share it with others who might benefit.



Source link

Leave a Reply

Your email address will not be published. Required fields are marked *