Skip to content

General: Improve caching in get_calendar function#11547

Open
MarcinDudekDev wants to merge 1 commit intoWordPress:trunkfrom
MarcinDudekDev:trac/61343
Open

General: Improve caching in get_calendar function#11547
MarcinDudekDev wants to merge 1 commit intoWordPress:trunkfrom
MarcinDudekDev:trac/61343

Conversation

@MarcinDudekDev
Copy link
Copy Markdown

Summary

  • Replace monolithic calendar cache (single array with all variations) with individual cache keys per variation — reduces deserialization overhead on reads
  • Switch invalidation hooks from save_post/delete_post to clean_post_cache — avoids unnecessary flushes on autosaves, revisions, and draft saves
  • Use wp_cache_flush_group('calendar') for invalidation with a generation counter fallback for object cache implementations lacking group flush support
  • Replace MySQL date arithmetic (DATE_FORMAT/DATE_ADD) with PHP native gmdate() — eliminates unnecessary DB roundtrip

Technical Details

Cache Architecture (before → after)

Before: All calendar variations stored in one serialized array under key get_calendar. Every read deserializes all months/post-types. Every write re-serializes the entire array. delete_get_calendar_cache() nukes everything via wp_cache_delete.

After: Each variation gets its own cache key (get_calendar_{hash}). Reads fetch only the requested entry. delete_get_calendar_cache() uses wp_cache_flush_group('calendar') to clear all entries.

Persistent Cache Compatibility

Object cache implementations that don't support flush_group get a generation counter fallback: delete_get_calendar_cache() increments a generation value, and the cache key includes that generation — effectively invalidating all previous entries without needing to enumerate them.

Raw SQL Queries Preserved

The ticket suggested replacing $wpdb queries with WP_Query, but SELECT DISTINCT DAYOFMONTH(post_date) returns max 31 rows while WP_Query would load all posts in the month. The existing PR #6708 makes this replacement and introduces a performance regression. We keep the efficient raw queries.

Trac ticket: https://core.trac.wordpress.org/ticket/61343
Supersedes: #6708

Test plan

  • All 10 existing + new tests pass (27 assertions)
  • PHPCS clean on all 3 modified files
  • Cache invalidation works via delete_get_calendar_cache()
  • Individual cache keys: different post types cached independently
  • flush_group clears all variations at once
  • Backwards compatibility: delete_get_calendar_cache() function signature unchanged
  • Verify with a persistent object cache plugin (Redis/Memcached)

AI assistance: Yes
Tool(s): Claude Code (Anthropic)
Model(s): Claude Opus 4.6
Used for: Performance analysis, identifying regression in existing PR #6708, implementation of cache restructure with generation counter fallback, and writing unit tests. All code was reviewed and tested.


This Pull Request is for code review only. Please keep all other discussion in the Trac ticket. Do not merge this Pull Request. See GitHub Pull Requests for Code Review in the Core Handbook for more details.

🤖 Generated with Claude Code

Replace the monolithic calendar cache (single array storing all variations)
with individual cache keys per calendar variation, reducing deserialization
overhead on cache reads.

Switch cache invalidation from `save_post` and `delete_post` hooks to
`clean_post_cache`, which avoids unnecessary cache flushes on autosaves,
revision cleanup, and draft saves.

Use `wp_cache_flush_group()` to invalidate all calendar cache entries,
with a generation counter fallback for object cache implementations
that do not support group flushing.

Replace MySQL date arithmetic query with PHP native `gmdate()` to
eliminate an unnecessary database roundtrip for week-to-month
calculation.

Props spacedmonkey, narenin.
Fixes #61343.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown

The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the props-bot label.

Core Committers: Use this line as a base for the props when committing in SVN:

Props myththrazz.

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

@github-actions
Copy link
Copy Markdown

Test using WordPress Playground

The changes in this pull request can previewed and tested using a WordPress Playground instance.

WordPress Playground is an experimental project that creates a full WordPress instance entirely within the browser.

Some things to be aware of

  • All changes will be lost when closing a tab with a Playground instance.
  • All changes will be lost when refreshing the page.
  • A fresh instance is created each time the link below is clicked.
  • Every time this pull request is updated, a new ZIP file containing all changes is created. If changes are not reflected in the Playground instance,
    it's possible that the most recent build failed, or has not completed. Check the list of workflow runs to be sure.

For more details about these limitations and more, check out the Limitations page in the WordPress Playground documentation.

Test this pull request with WordPress Playground.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant