Improved Caching for Database Queries in WP_User_Query

In WordPress 6.3, significant enhancements have been made to the WP_User_Query class, specifically regarding caching of database queries. This update builds upon the ongoing efforts of the performance team to optimize query caching for various WordPress CoreCore Core is the set of software required to run WordPress. The Core Development Team builds WordPress. query classes. WP_Query introduced query caching in WordPress 6.1, while other query classes like WP_Comment_Query, WP_Site_Query, WP_Network_Query, and WP_Term_Query already had built-in query caching. As a result, WP_User_Query was the only remaining query class lacking this caching capability.

The implementation of query caching in WP_User_Query aligns with that of other query classes. Once a query is executed, the resulting database queries are cached, and subsequent queries with the same parameters will retrieve the data from the cache. This caching behavior, when combined with persistent object caching, ensures that the database query won’t be executed again until the caches are invalidated, leading to a substantial reduction in overall database queries. Even sites using in-memory caching will benefit from avoiding repetitive queries, although the performance improvement may not be as significant.

It’s important to note that starting from this version onward, all calls to WP_User_Query will be automatically cached by default. However, if you wish to disable query caching for specific queries, you can simply set the cache_results parameter to false, as demonstrated in the following example:

$args = array(

   'number' => 50,

   'cache_results' => false

);

$query = new WP_User_Query( $args );

Alternatively, you can globally disable caching by using a filterFilter Filters are one of the two types of Hooks https://codex.wordpress.org/Plugin_API/Hooks. They provide a way for functions to modify data of other functions. They are the counterpart to Actions. Unlike Actions, filters are meant to work in an isolated manner, and should never have side effects such as affecting global variables and output., as shown below:

function disable_caching( $wp_user_query ) {

   $wp_user_query->query_vars['cache_results'] = false;

}

add_action( 'pre_get_users', 'disable_caching' );

For developers working on custom solutions, it’s essential to utilize Core functions such as wp_insert_user for adding users to the database. These functions are well-maintained and ensure proper cache invalidation. If you directly update the database, it is strongly recommended to call the clean_user_cache function after modifying the respective database row.

With this update, a new global cache group called user-queries is introduced to store the results of queries. If your site uses persistent object caching, make sure it supports adding global cache groups by utilizing the wp_cache_add_global_groups function, introduced in WP 2.6. If not, you will need to manually add the three new global cache groups.

It’s worth noting that caching will be disabled for user queries that utilize the field parameter and request more than 3 fields. This decision is made to prevent cache values from becoming excessively large and to avoid filling up caches with data unlikely to be reused.

Lastly, plugins utilizing the users_pre_query hook to modify the returned values will bypass caching and continue to function as they did in previous versions of WordPress.

For additional context on the changes, please see #40613.

Props to @flixos90 and @adamsilverstein for peer review, to @stevenlinx for review.

#6-3, #dev-notes, #dev-notes6-3