Plugin purges Object Cache
The support doesn work on Saturdays and Sundays, so some Friday requests can be answered on Monday. If you have problems with registration ask help on contact us page pleaseIf you not got email within 24~36 business hours, firstly check your spam box, and if no any email from the support there - back to the forum and read answer here. DO NOT ANSWER ON EMAILS [noreply@pluginus.net] FROM THE FORUM!! Emails are just for your info, all answers should be published only here.
The support doesn work on Saturdays and Sundays, so some Friday requests can be answered on Monday.
Support notice: Our support team will be on vacation from August 8 to September 3, so response times may be delayed and replies may be irregular.
Quote from Jeff1 on August 20, 2026, 07:51Hi!
Regarding this issue: https://pluginus.net/support/topic/filter-lost-on-pagination-filter-bulk-can-hit-entire-catalog-progress-stuck-at-98-v2-2-1/
I have exact same problem with pagination and bulk edit.
I have redis object cache. Tried to investigate.
Here's what happens:
1. BEAR stores filters in a transient (lib/storage.php:31,40-45)
WOOBE_STORAGE is type = 'transient', key = md5($_SERVER['REMOTE_ADDR'] . 'woobe_salt'), with the active filter inside it as woobe_filter_<filter_current_key> (ext/filters/filters.php:64,886).
2. The filter is re-read on every DataTables AJAX call (ext/filters/filters.php:885-887 → classes/models/products.php:112). Pagination depends entirely on that re-read. This is why the filter "doesn't persist" — page 2 never sends the filter data, it re-reads it from storage.
3. wp_cache_flush() on every table load (index.php:623, inside woobe_get_products)
With the default non-persistent object cache, wp_cache_flush() only clears the in-request cache. Transients fall back to the DB options table, so nothing is lost.
With Redis (your drop-in at wp-content/object-cache.php:1671), wp_cache_flush() runs a real FLUSHDB wiping every key in Redis.
With an external object cache, WP stores transients only in Redis, never in the DB. So the flush permanently destroys the transient holding active filter.
Sequence: apply filter → transient written to Redis → table loads page 1 → woobe_get_products runs, then wp_cache_flush() deletes the filter transient → page 2 re-reads storage → empty → unfiltered catalog. Same reason filter-based bulk breaks.
Every BEAR table load also nukes Redis for the entire site (sessions, page caches, ElasticPress, everything), forcing a full cache rebuild — huge performance hit on a 60k-product catalog, which very plausibly contributes to the "stuck at 98%" behavior.The fix comment out wp_cache_flush() in woo-bulk-editor/index.php:623
if ( $products->found_posts > 0 ) {$products_types = array();$products_titles = array();// wp_cache_flush();foreach ( $products->posts as $p ) {
Hi!
Regarding this issue: https://pluginus.net/support/topic/filter-lost-on-pagination-filter-bulk-can-hit-entire-catalog-progress-stuck-at-98-v2-2-1/
I have exact same problem with pagination and bulk edit.
I have redis object cache. Tried to investigate.
Here's what happens:
1. BEAR stores filters in a transient (lib/storage.php:31,40-45)
WOOBE_STORAGE is type = 'transient', key = md5($_SERVER['REMOTE_ADDR'] . 'woobe_salt'), with the active filter inside it as woobe_filter_<filter_current_key> (ext/filters/filters.php:64,886).
2. The filter is re-read on every DataTables AJAX call (ext/filters/filters.php:885-887 → classes/models/products.php:112). Pagination depends entirely on that re-read. This is why the filter"doesn't persist" — page 2 never sends the filter data, it re-reads it from storage.
3. wp_cache_flush() on every table load (index.php:623, inside woobe_get_products)
With the default non-persistent object cache, wp_cache_flush() only clears the in-request cache. Transients fall back to the DB options table, so nothing is lost.
With Redis (your drop-in at wp-content/object-cache.php:1671), wp_cache_flush() runs a real FLUSHDB wiping every key in Redis.
With an external object cache, WP stores transients only in Redis, never in the DB. So the flush permanently destroys the transient holding active filter.
Sequence: apply filter → transient written to Redis → table loads page 1 → woobe_get_products runs, then wp_cache_flush() deletes the filter transient → page 2 re-reads storage → empty → unfiltered catalog. Same reason filter-based bulk breaks.
Every BEAR table load also nukes Redis for the entire site (sessions, page caches, ElasticPress, everything), forcing a full cache rebuild — huge performance hit on a 60k-product catalog, which very plausibly contributes to the"stuck at 98%" behavior.
The fix comment out wp_cache_flush() in woo-bulk-editor/index.php:623
Quote from Alex Dev on August 20, 2026, 11:17Hello Jeff
Thank you for taking the time to dig into the code before writing.
We have already made the changes. The public release is planned for autumn, but you do not have to wait for it: an updated build is attached in the private section of this ticket, so you can install it today.
Here is what was done and why.
- A switch for the cache flush.
The call to wp_cache_flush() is now wrapped in a filter. Add this to your theme functions.php or to a small mu-plugin, and the plugin will stop flushing the object cache:
add_filter( 'woobe_use_cache_flush', '__return_false' );
The default stays as it is, so nothing changes for anyone who does not add this line.
We will not remove that call for everyone, and it is worth explaining why rather than just saying no. It sits in the read path of the products table, right before the rows are built. Its job is to make sure the table shows the current values and not what was cached before the last edit. On the majority of installations there is no persistent object cache at all, and there wp_cache_flush() only clears the per request cache, which costs nothing. Removing it by default would mean that a large number of users would start seeing stale values in the table right after editing them, with no way to understand why. That is a worse failure than the one it causes on your setup, because it is silent and it leads people to distrust the data they are editing.
On your side the trade off is different and it is now yours to make: with the filter in place the table may occasionally show a value that was changed a moment ago until you reload, and in exchange your Redis instance is left alone. Just to set expectations: this affects what you see in the plugin table, not your front end. Stale prices or stock on the shop pages come from page caching and WooCommerce transients, and that layer is outside the plugin's control either way.
- The storage class has been rewritten, and this is the part that actually fixes the pagination and bulk behaviour.
The plugin has to remember the active filter and the bulk payload between requests, because page two of the table does not resend the filter, it re-reads it. Until now that data was kept in a transient. On a site without a persistent object cache a transient lives in the wp_options table, so it survives anything. With an external object cache, WordPress stores transients in the cache only and never writes them to the database, so a flush destroys them permanently. That is why the filter disappeared on paging for you and why a bulk operation could end up with no filter conditions at all.
The storage now uses a plain option row instead. An option always exists in the database, so a cache flush can evict it from memory but can never destroy it: the next read simply loads it back. The same class also stores the bulk payload and the progress counter, so those are protected now too.
Two more things changed along with it. The storage key used to be derived from the visitor IP address, which broke behind proxies and CDNs where the address can change between requests, and which merged two administrators working from the same office network into one shared key. It is now keyed by user ID, so each administrator has their own isolated storage. The row is stored without autoload, so it is never loaded on regular site pages, and entries expire on the same one day schedule the transient used, so nothing accumulates.
There is also a storage type selector on the plugin settings page now, in case you ever want to go back to the previous behaviour. The filter woobe_storage_type still works and takes priority over the setting.
Please make tests and give us your feedback ...
Hello Jeff
Thank you for taking the time to dig into the code before writing.
We have already made the changes. The public release is planned for autumn, but you do not have to wait for it: an updated build is attached in the private section of this ticket, so you can install it today.
Here is what was done and why.
- A switch for the cache flush.
The call to wp_cache_flush() is now wrapped in a filter. Add this to your theme functions.php or to a small mu-plugin, and the plugin will stop flushing the object cache:
add_filter( 'woobe_use_cache_flush', '__return_false' );
The default stays as it is, so nothing changes for anyone who does not add this line.
We will not remove that call for everyone, and it is worth explaining why rather than just saying no. It sits in the read path of the products table, right before the rows are built. Its job is to make sure the table shows the current values and not what was cached before the last edit. On the majority of installations there is no persistent object cache at all, and there wp_cache_flush() only clears the per request cache, which costs nothing. Removing it by default would mean that a large number of users would start seeing stale values in the table right after editing them, with no way to understand why. That is a worse failure than the one it causes on your setup, because it is silent and it leads people to distrust the data they are editing.
On your side the trade off is different and it is now yours to make: with the filter in place the table may occasionally show a value that was changed a moment ago until you reload, and in exchange your Redis instance is left alone. Just to set expectations: this affects what you see in the plugin table, not your front end. Stale prices or stock on the shop pages come from page caching and WooCommerce transients, and that layer is outside the plugin's control either way.
- The storage class has been rewritten, and this is the part that actually fixes the pagination and bulk behaviour.
The plugin has to remember the active filter and the bulk payload between requests, because page two of the table does not resend the filter, it re-reads it. Until now that data was kept in a transient. On a site without a persistent object cache a transient lives in the wp_options table, so it survives anything. With an external object cache, WordPress stores transients in the cache only and never writes them to the database, so a flush destroys them permanently. That is why the filter disappeared on paging for you and why a bulk operation could end up with no filter conditions at all.
The storage now uses a plain option row instead. An option always exists in the database, so a cache flush can evict it from memory but can never destroy it: the next read simply loads it back. The same class also stores the bulk payload and the progress counter, so those are protected now too.
Two more things changed along with it. The storage key used to be derived from the visitor IP address, which broke behind proxies and CDNs where the address can change between requests, and which merged two administrators working from the same office network into one shared key. It is now keyed by user ID, so each administrator has their own isolated storage. The row is stored without autoload, so it is never loaded on regular site pages, and entries expire on the same one day schedule the transient used, so nothing accumulates.
There is also a storage type selector on the plugin settings page now, in case you ever want to go back to the previous behaviour. The filter woobe_storage_type still works and takes priority over the setting.
Please make tests and give us your feedback ...
Quote from Jeff1 on August 20, 2026, 12:47Thanks for thorough explanation. I reviewed this part:
/*** Allows to disable the object cache flush before the table rows are built.** The flush is here to make sure the rows below show the actual product data* and not the values cached before the last edit. On sites with a persistent* object cache (Redis, Memcached) a full flush is expensive and affects the* whole site, so it can be turned off - at the cost of possibly seeing* outdated values in the table.** @param bool $do_flush*/if ( apply_filters( 'woobe_use_cache_flush', true ) ) {wp_cache_flush();}It's good solution for now and we will use it. Thanks!
Thanks for thorough explanation. I reviewed this part:
