Bulk operation cache strategy

Bulk saves create or update dozens of posts in one request. Left to default behavior, each row would trigger the full save pipeline and a page-cache purge, making the request CPU-bound. Fenómenus takes a deliberate approach that integrations should match.

What a bulk save does

Around the loop:

  1. Defer term counting, restoring the previous value afterwards.
  2. Suspend cache invalidation for the duration, restoring it afterwards.
  3. Enter bulk save mode, which suppresses edit-screen side effects.
  4. Suppress per-row page-cache purges through a filter.

After the loop, in a finally block:

  1. Restore term counting and cache invalidation.
  2. Clean the post cache for each touched post.
  3. Remove the purge suppression filter.
  4. Purge the page cache once, if anything changed.

The purge filter

Per-row purging is suppressed by returning false from the page cache's own decision filter:

add_filter( 'pom_cache_should_delete_site_cache', 'pom_rm_disable_pom_cache_flush', 10, 2 );
// … the batch …
remove_filter( 'pom_cache_should_delete_site_cache', 'pom_rm_disable_pom_cache_flush', 10 );

A single purge is then issued for the whole batch, with a context string identifying the operation.

The result: one purge per import instead of one per row, and a public menu that updates in a single step when the batch finishes.

Bulk save mode

While the mode is active, edit-screen behaviors are skipped:

  • automatic featured-image detection from the gallery;
  • automatic category assignment on publish.

That is why an import with no category selected leaves items uncategorised rather than filing them arbitrarily.

Custom code that hooks save_post for these post types should check the mode and skip work that only makes sense for a single interactive edit:

if ( function_exists( 'pom_rm_is_bulk_post_save_mode' ) && pom_rm_is_bulk_post_save_mode() ) {
    return;
}

Ordering writes

Moving a matched row to the end of the menu order updates only menu_order, on a row already resolved by ID, rather than running a full post update. Post caches for touched IDs are cleaned once after the batch.

Reproduce that pattern in custom bulk tools: a full update per row to change one integer is the most common cause of a slow import.

Implications for other caches

The single purge covers the site's own page cache. It does not:

  • invalidate a CDN;
  • rebuild a generated PDF;
  • update anything printed.

A bulk change therefore ends with three manual considerations: purge the edge if one exists, regenerate PDFs, and check whether any printed material referenced something that moved.

Guidance for custom bulk tools

  1. Defer term counting and suspend cache invalidation around the loop.
  2. Enter bulk save mode so the product's own side effects are skipped.
  3. Suppress per-row purges and issue one at the end.
  4. Clean post caches for touched IDs.
  5. Restore every flag in a finally block, so an exception cannot leave the site with invalidation suspended.