{"id":19014528,"date":"2026-09-08T13:32:32","date_gmt":"2026-09-08T13:32:32","guid":{"rendered":"https:\/\/wordpress.org\/support\/topic\/bug-bulk-editing-posts-does-not-invalidate-redis-object-cachepost-lists-remai\/"},"modified":"2026-09-08T13:32:32","modified_gmt":"2026-09-08T13:32:32","slug":"bug-bulk-editing-posts-does-not-invalidate-redis-object-cachepost-lists-remai","status":"publish","type":"topic","link":"https:\/\/wordpress.org\/support\/topic\/bug-bulk-editing-posts-does-not-invalidate-redis-object-cachepost-lists-remai\/","title":{"rendered":"Bug: Bulk editing posts does not invalidate Redis Object Cache(post lists remai)"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Environment Details<\/p>\n\n\n\n<ul>\n<li><strong>WordPress Version<\/strong>: 7.1<\/li>\n\n\n\n<li><strong>W3 Total Cache Version<\/strong>: Latest<\/li>\n\n\n\n<li><strong>Object Cache Backend<\/strong>: Redis 8.6.6<\/li>\n\n\n\n<li><strong>Server Stack<\/strong>: Nginx + PHP-FPM + Redis<\/li>\n\n\n\n<li><strong>Active W3TC Modules<\/strong>: Page Cache(Enhancement), Object Cache (Redis), Browser\u00a0Cache<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Description<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">When bulk editing posts via the WordPress admin dashboard (e.g., selecting multiple drafts and changing their status to &#8220;Published&#8221;), the Redis object cache for <code>WP_Query<\/code> \/ post lists is not invalidated.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">As a result, frontend archive pages, the homepage blog loop, and category lists continue serving the stale post list from Redis.Steps to Reproduce<\/p>\n\n\n\n<ol start=\"1\">\n<li>Enable <strong>Object Cache<\/strong> in W3 Total Cache settings using <strong>Redis<\/strong> as the caching engine.<\/li>\n\n\n\n<li>In WP Admin, navigate to <strong>Posts -&gt; All Posts<\/strong>.<\/li>\n\n\n\n<li>Select 2 or more draft posts via the checkboxes.<\/li>\n\n\n\n<li>Select <strong>Bulk Actions -&gt; Edit -&gt; Apply<\/strong>.<\/li>\n\n\n\n<li>Change <strong>Status<\/strong> to <strong>Published<\/strong> and click <strong>Update<\/strong>.<\/li>\n\n\n\n<li>Visit the frontend homepage or blog archive in an incognito window.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">Expected Behavior<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The frontend post list \/ archive should immediately display the newly published posts, as the query cache holding the post lists should be invalidated upon status transition.Actual Behavior<\/p>\n\n\n\n<ul>\n<li>The newly published posts do not appear in the frontend loop.<\/li>\n\n\n\n<li>Individual posts are accessible directly via their permalinks, confirming they were successfully published in MySQL.<\/li>\n\n\n\n<li>The frontend query list remains stuck until Redis is manually flushed or invalidated.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Troubleshooting &amp; Diagnostic Findings<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">To isolate the exact point of failure, I conducted the following tests:<\/p>\n\n\n\n<ol start=\"1\">\n<li><strong>Subsequent single-post update flushes the queue<\/strong>: If I edit and update any single post individually right after the bulk edit, the frontend post list immediately refreshes and displays all the previously bulk-published posts. This indicates that single-post save hooks trigger cache invalidation properly, whereas bulk editing skips or suppresses the invalidation signal.<\/li>\n\n\n\n<li><strong>Restarting Redis immediately forces a refresh<\/strong>: Restarting the Redis service (or executing <code>redis-cli flushall<\/code>) immediately resolves the issue and the frontend post list shows the updated posts. This confirms the stale query results are strictly held in volatile Redis memory rather than persistent database storage\/transients.<\/li>\n\n\n\n<li><strong>Issue is strictly tied to Object Caching<\/strong>: Disabling <strong>Object Cache<\/strong> in W3TC completely resolves the issue. Frontend queries hit MySQL directly and reflect changes instantly after bulk editing.<\/li>\n\n\n\n<li><strong>Vendor-specific to W3TC&#8217;s Redis implementation<\/strong>: Keeping W3TC for Page Cache\/Minify, disabling W3TC&#8217;s Object Cache, and switching to the standalone <a href=\"https:\/\/wordpress.org\/plugins\/redis-cache\/?utm_source=gemini\" target=\"_blank\" rel=\"noreferrer noopener\">Redis Object Cache<\/a> plugin completely resolves the issue. Bulk edits invalidate the post list immediately under the exact same server and Redis setup.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">Core Refactor Suspicion &amp; Technical Context<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">I recall that recent <strong>WordPress 7.x release notes highlighted major refactoring around the admin post list table (modernizing list architecture \/ Data Views \/ batch processing pipelines)<\/strong>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">It is very likely that the updated post list table altered how batch updates and lifecycle hooks are dispatched during bulk operations:<\/p>\n\n\n\n<ul>\n<li>In modern WordPress, <code>WP_Query<\/code> caches results in the persistent object cache using <code>posts_last_changed<\/code>.<\/li>\n\n\n\n<li>If the refactored admin post list deferred standard save actions or routed bulk status changes through an optimized pipeline, legacy object cache listeners might fail to catch the batch event.<\/li>\n\n\n\n<li>As a result, <code>wp_cache_set_posts_last_changed()<\/code> is not invoked at the end of the routine, leaving the <code>posts<\/code> cache group&#8217;s <code>last_changed<\/code> key untouched in Redis while the MySQL records have already updated.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Could you please investigate compatibility with the refactored WP 7.x post list workflows and ensure a listener for <code>bulk_edit_posts<\/code> (or reliable execution of <code>wp_cache_set_posts_last_changed()<\/code>) is tied into the bulk update completion?<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n","protected":false},"template":"","class_list":["post-19014528","topic","type-topic","status-publish","hentry"],"jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/wordpress.org\/support\/wp-json\/wp\/v2\/topic\/19014528","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.org\/support\/wp-json\/wp\/v2\/topic"}],"about":[{"href":"https:\/\/wordpress.org\/support\/wp-json\/wp\/v2\/types\/topic"}],"version-history":[{"count":0,"href":"https:\/\/wordpress.org\/support\/wp-json\/wp\/v2\/topic\/19014528\/revisions"}],"wp:attachment":[{"href":"https:\/\/wordpress.org\/support\/wp-json\/wp\/v2\/media?parent=19014528"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}