#63045 closed enhancement (fixed)
Add caching to `count_many_users_posts()`
| Reported by: |
|
Owned by: |
|
|---|---|---|---|
| Milestone: | 6.9 | Priority: | normal |
| Severity: | normal | Version: | |
| Component: | Users | Keywords: | has-patch has-unit-tests needs-testing |
| Focuses: | performance | Cc: |
Description
Follow up to #39242, specifically as raised in https://core.trac.wordpress.org/ticket/39242#comment:39: As we already added caching to count_user_posts(), it makes sense to add similar caching to count_many_users_posts().
cc @spacedmonkey @peterwilsoncc
Attachments (1)
Change History (29)
This ticket was mentioned in PR #8444 on WordPress/wordpress-develop by @sukhendu2002.
8 months ago
#1
- Keywords has-patch added; needs-patch removed
This ticket was mentioned in Slack in #core by jeffpaul. View the logs.
8 months ago
This ticket was mentioned in Slack in #core by jeffpaul. View the logs.
8 months ago
This ticket was mentioned in Slack in #core-performance by adamsilverstein. View the logs.
5 months ago
This ticket was mentioned in PR #9106 on WordPress/wordpress-develop by @rollybueno.
4 months ago
#6
Add proper caching support to count_many_users_posts() function
Enhances the performance of count_many_users_posts() function with working cache key generation.
Trac ticket: https://core.trac.wordpress.org/ticket/63045
#7
@
4 months ago
I'm not a fan of md5() the query statement so I pushed a new patch version in https://github.com/WordPress/wordpress-develop/pull/9106/ that:
- More transparent cache keys – avoids md5() and instead uses readable, parameter-based keys (user IDs, post type,
$public_only), which makes it easier to debug and trace. - Proper separation of cached data – different input combinations get unique keys, reducing the risk of stale or incorrect cache results.
- Better cache grouping – avoids using a static group, so it's safer and more aligned with how the query behaves.
- Easier to maintain or extend – the logic is clearer and more flexible for future changes.
Overall, it's a more accurate, debuggable, and scalable approach to caching in count_many_users_posts().
My questions:
- ❓ Should we have the OC an expiration? If yes, how long? I have set to 1 hour but it's open for discussions.
- ❓ We probably need cache clearing function, but on what actions it should hook into?
This ticket was mentioned in Slack in #core-performance by rollybueno. View the logs.
4 months ago
#9
@
4 months ago
- Keywords 2nd-opinion dev-feedback added
During the bi-weekly coffee-hours, this needs more discussion regarding the caching approach, either using readable cache key or using md5.
Props @flixos90
#10
@
4 months ago
I strongly believe we should work on #59592 first, as that will effect this ticket's approach.
#11
@
3 months ago
Add object caching to count_many_users_posts() to avoid repeated database queries, similar to count_user_posts().
#12
@
2 months ago
- Keywords needs-refresh added
I checked the PR https://github.com/WordPress/wordpress-develop/pull/9106/files and 63045-cache-count_many_users_posts.diff
The issue with both approaches is different cache_key would be generated if order of array $users is different
$userlist = implode( ',', array_map( 'absint', $users ) );
$cache_key = "count_many_users_posts_{$post_type}_{$public_only}_" . str_replace( ',', '_', $userlist ) . '_' . get_current_user_id();
For above code,
$users = [ 1, 2, 3 ] → $userlist = "1,2,3" → _1_2_3_ in the cache key. $users = [ 3, 2, 1 ] → $userlist = "3,2,1" → _3_2_1_ in the cache key.
To fix this, we should normalize the $users array before building the key:
- Ensure all IDs are integers.
- Remove duplicates.
- Sort the array to guarantee consistent order.
Here is the suggested fix for this,
$users = array_map( 'absint', (array) $users );
$users = array_filter( $users ); // remove 0/invalids
$users = array_unique( $users ); // remove duplicates
sort( $users ); // enforce consistent order
$userlist = implode( '_', $users );
$cache_key = "count_many_users_posts_{$post_type}_{$public_only}_{$userlist}_" . get_current_user_id();
#13
@
2 months ago
- Keywords changes-requested added; needs-refresh removed
Hey @kalpeshh, for your information, needs-refresh means, that the patch is not applying correctly. What I think you were trying to add is changes-requested. I'm adding this for you.
This ticket was mentioned in Slack in #core-performance by westonruter. View the logs.
2 months ago
#16
@
7 weeks ago
Thanks for the feedback @kalpeshh! Updated https://github.com/WordPress/wordpress-develop/pull/9106.
I just noticed, however, that @spacedmonkey has also requested feedback on https://github.com/WordPress/wordpress-develop/pull/8444 , which I only saw after I have updated my branch.
By the way that PR has unit test(still need some polishing) so I' think we should use that instead of mine.
Keeping the existing keywords for https://github.com/WordPress/wordpress-develop/pull/8444
#17
@
7 weeks ago
- Keywords needs-testing added; 2nd-opinion dev-feedback changes-requested removed
Update: @peterwilsoncc and @westonruter have reviewed PR https://github.com/WordPress/wordpress-develop/pull/9106, and I’ve applied their feedback. The changes include:
- Switching to md5 for the cache key to handle Memcached’s 250-character limit
- Replacing with
wp_cache_get_salted() - Adding a dedicated unit test function specifically for this ticket
Marking the ticket as needs testing.
This ticket was mentioned in Slack in #core by wildworks. View the logs.
4 weeks ago
#19
@
4 weeks ago
This ticket was featured on today's 6.9 Bug Scrub. We need to test the updated PR.
@peterwilsoncc commented on PR #9106:
3 weeks ago
#20
I think the tests could do with a little work to ensure the cache is hit, invalidated correctly and to ensure against public/private collisions.
@rollybueno I'll take the liberty of pushing the changes to your branch as the beta is approaching
@peterwilsoncc commented on PR #9106:
3 weeks ago
#21
@rollybueno I've pushed the tests changes:
The main purpose was to split the tests out in to individual items rather than one big mega test. This is to make it clearer for devs if something starts failing in the future.
For the caching tests, I also added tests for the number of database queries on the second call of the function. This ensures that the cache is hit rather than the database. I did similar for cache invalidation tests, but in those cases a call to the database is expected.
I've also added some tests that equivalent arguments it the cache, eg querying [ posts, pages ] hits the same cache as [ pages, posts ]. For this I discovered a bug that I've pushed a code fix for.
Ignore the failing build processes tests, that's unrelated to this pull request.
@peterwilsoncc commented on PR #9106:
3 weeks ago
#22
Thanks @shail-mehta, I've fixed the ticket references in each of the tests.
#25
@
3 weeks ago
- Resolution fixed deleted
- Status changed from closed to reopened
@peterwilsoncc I would tweak the logic here.
$where = get_posts_by_author_sql( $post_type, true, null, $public_only );
$query = "SELECT post_author, COUNT(*) FROM $wpdb->posts $where AND post_author IN ($userlist) GROUP BY post_author";
...
if ( false === $count ) {
$result = $wpdb->get_results( $query, ARRAY_N );
This ticket was mentioned in PR #10336 on WordPress/wordpress-develop by @peterwilsoncc.
3 weeks ago
#26
Removes duplicate logic generating the SQL query from the function.
Follow up to r60941, https://github.com/WordPress/wordpress-develop/commit/bb4d8706d0fea1a836eeed8d097c29368433d017
Trac ticket: https://core.trac.wordpress.org/ticket/63045
Trac ticket: https://core.trac.wordpress.org/ticket/63045