Skip to content

Replace post meta sync storage with dedicated sync_updates table#11068

Open
josephfusco wants to merge 1 commit intoWordPress:trunkfrom
josephfusco:feature/sync-updates-table
Open

Replace post meta sync storage with dedicated sync_updates table#11068
josephfusco wants to merge 1 commit intoWordPress:trunkfrom
josephfusco:feature/sync-updates-table

Conversation

@josephfusco
Copy link

The real-time collaboration sync layer currently stores messages as post meta, which works but creates side effects at scale. This moves it to a dedicated wp_sync_updates table purpose-built for the workload.

The beta1 implementation stores sync messages as post meta on a private wp_sync_storage post type. Post meta is designed for static key-value data, not high-frequency transient message passing. This mismatch causes:

  1. Cache thrashing — Every sync write triggers wp_cache_set_posts_last_changed(), invalidating site-wide post query caches unrelated to collaboration.

  2. Compaction race condition — The "delete all, re-add some" pattern in remove_updates_before_cursor() loses messages under concurrent writes. The window between delete_post_meta() and the add_post_meta() loop is unprotected.

  3. Cursor race condition — Timestamp-based cursors (microtime() * 1000) miss updates when two writes land within the same millisecond.

A purpose-built table with auto-increment IDs eliminates all three at the root: no post meta hooks fire, compaction is a single atomic DELETE, and auto-increment IDs guarantee unique ordering. The WP_Sync_Storage interface and WP_HTTP_Polling_Sync_Server are unchanged.

Also adds a wp_sync_storage filter so hosts can substitute alternative backends (Redis, WebSocket) without patching core, and includes a beta1 upgrade path that cleans up orphaned wp_sync_storage posts.

Credits

Trac ticket: https://core.trac.wordpress.org/ticket/64696

Use of AI Tools

Co-authored with Claude Code (Opus 4.6), used to synthesize discussion across related tickets and PRs into a single implementation. All code was reviewed and tested before submission.


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.

@github-actions
Copy link

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 joefusco.

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

@github-actions
Copy link

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.

@josephfusco josephfusco changed the title feat: replace post meta sync storage with dedicated sync_updates table Replace post meta sync storage with dedicated sync_updates table Feb 26, 2026
Copy link
Contributor

@peterwilsoncc peterwilsoncc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First pass note inline.

This approach had occurred to me and I think it's probably quite a good idea.

But, as always, there is a but.

I know @m has been reluctant in the past to add new tables to the database schema. I guess (and Matt will be able to correct me) that's to avoid ending up with a database scheme of dozens and dozens of tables.

As not all sites run the database upgrade routine on a regular basis (I think wordpress.org is often behind) as it can be quite a burden on a site, if this approach is to be taken it would need to include a check for the table's existence in a couple of locations:

  • The option_{$option} hook
  • Before displaying the options field on the writing page

Some form of filtering would need to be available for sites that are using custom data stores.

Sorry to be that person. I'm not trying to be negative, just share knowledge I've learnt over the last few years.

Comment on lines +2511 to +2520

// Clean up orphaned wp_sync_storage posts from the beta1 post-meta storage approach.
if ( $wp_current_db_version < 61697 ) {
$wpdb->delete( $wpdb->postmeta, array( 'meta_key' => 'wp_sync_update' ) );
$wpdb->delete( $wpdb->postmeta, array( 'meta_key' => 'wp_sync_awareness' ) );
$wpdb->delete(
$wpdb->posts,
array( 'post_type' => 'wp_sync_storage' )
);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need to do this as the code was never released so these should not be in production environments, just burner environments. Anyone running the beta on production environments can be responsible for their own tidy up.

The code above can be reverted too but the DB version change will be required in version.php

Suggested change
// Clean up orphaned wp_sync_storage posts from the beta1 post-meta storage approach.
if ( $wp_current_db_version < 61697 ) {
$wpdb->delete( $wpdb->postmeta, array( 'meta_key' => 'wp_sync_update' ) );
$wpdb->delete( $wpdb->postmeta, array( 'meta_key' => 'wp_sync_awareness' ) );
$wpdb->delete(
$wpdb->posts,
array( 'post_type' => 'wp_sync_storage' )
);
}

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.

2 participants