Opened 5 weeks ago
Last modified 4 weeks ago
#65486 new enhancement
Performance: Avoid redundant cache invalidation in WP_REST_Meta_Fields during batch meta updates
| Reported by: | spacedmonkey | Owned by: | |
|---|---|---|---|
| Priority: | normal | Milestone: | Awaiting Review |
| Component: | REST API | Version: | |
| Severity: | normal | Keywords: | good-first-bug has-patch has-unit-tests |
| Cc: | Focuses: | rest-api, performance |
Description
The Problem
The WP_REST_Meta_Fields class handles updating, adding, and deleting metadata for various object types via the REST API. When a request modifies multiple meta keys at once, it iterates through them and performs the updates individually.
These operations trigger Core's cache invalidation hooks via the underlying added_*_meta, updated_*_meta, and deleted_*_meta hooks.
When a REST API request updates a large batch of meta fields for an object, the object's last_changed cache is cleared and reset repeatedly in the same request execution. This creates unnecessary overhead for database and object cache layers.
The Proposed Solution
We should temporarily unhook the _last_changed invalidation functions before processing multiple meta updates inside WP_REST_Meta_Fields, and re-hook them once the operations are complete.
To do this cleanly across different object types, each subclass extending WP_REST_Meta_Fields should define its specific cache invalidation callback function as a property. For example:
<?php class WP_REST_Post_Meta_Fields extends WP_REST_Meta_Fields { // ... protected $cache_callback = 'wp_cache_set_posts_last_changed'; }
Then, in the base WP_REST_Meta_Fields class, we can dynamically target the hooks using get_meta_type() and the subclass property:
<?php $meta_type = $this->get_meta_type(); // e.g., 'post', 'user', 'comment', 'term' $hook_name = "updated_{$meta_type}_meta"; // Temporarily unhook the redundant cache invalidation callback $has_action = false; if ( ! empty( $this->cache_callback ) ) { $has_action = remove_action( $hook_name, $this->cache_callback ); } // ... existing code that loops through and updates/deletes multiple meta keys ... // Re-hook after the batch operations complete if ( $has_action ) { add_action( $hook_name, $this->cache_callback ); }
Scope of Impact
WP_REST_Meta_Fieldsabstract class and its extending subclasses (WP_REST_Post_Meta_Fields,WP_REST_User_Meta_Fields,WP_REST_Comment_Meta_Fields,WP_REST_Term_Meta_Fields).- This optimization will significantly reduce object cache thrashing during complex REST API
POSTorPUTrequests carrying heavy meta payloads.
Change History (1)
This ticket was mentioned in PR #12225 on WordPress/wordpress-develop by @sainathpoojary.
4 weeks ago
#1
- Keywords has-patch has-unit-tests added
![(please configure the [header_logo] section in trac.ini)](/chrome/site/your_project_logo.png)
Optimizes WP_REST_Meta_Fields::update_value() to prevent redundant object cache invalidations during batch meta updates. By temporarily unhooking the last_changed callbacks during the update loop and firing them only once at the end, this avoids unnecessary cache thrashing.
Trac ticket: #65486