Real-time Sync

CelerSearch automatically keeps your search index synchronized with your WordPress content.

How It Works

Observers watch for WordPress events and trigger index updates:

Text
Post Saved → Observer Detects → Queue Update → Sync to Search Engine

Watched Events

Posts/Pages/Custom Post Types (PostChangesObserver):

EventHook
Post created or updatedwp_after_insert_post
Post permanently deletedbefore_delete_post
Post moved to trashtrashed_post
Watched meta key changedadded_post_meta / updated_post_meta / deleted_post_meta
Attachment added or updatedadd_attachment / attachment_updated
Attachment deleteddelete_attachment

WooCommerce Products: products are posts, so the same hooks apply. Variations are embedded inside the parent product document, so a product re-index refreshes them too.

WooCommerce Orders (OrderChangesObserver):

EventHook
Order createdwoocommerce_new_order
Order updatedwoocommerce_update_order
Order deletedwoocommerce_before_delete_order
Order trashedwoocommerce_trash_order
Order status changedwoocommerce_order_status_changed

Queue System

Background processing runs on Action Scheduler, which is bundled with the plugin (and shared with WooCommerce when both are active). When it's available, updates are queued instead of blocking the request:

Benefits

  • Non-blocking - Page saves don't wait for the search engine
  • Debouncing - Multiple rapid edits only trigger one sync
  • Visibility - Failed syncs are recorded in a sync error log

How Debouncing Works

When you save a post multiple times quickly:

  1. First save → schedules sync in 5 seconds
  2. Second save (2 seconds later) → cancels first, schedules new sync in 5 seconds
  3. Third save (1 second later) → cancels second, schedules new sync in 5 seconds
  4. No more edits → sync runs 5 seconds after last edit

This ensures only the final state is synced, reducing API calls to your search engine. Deletes are not debounced — they're queued as immediate async actions so removed content disappears from results quickly.

Without Action Scheduler

If Action Scheduler isn't available (or the queue is disabled via filter):

  • Updates happen inline (synchronously) during the request
  • May slow down post saves slightly
  • No debouncing of rapid edits

Sync still depends on WP-Cron running

CelerSearch doesn't schedule indexing on WP-Cron directly — real-time updates go through the Action Scheduler queue. But that queue is processed by Action Scheduler's runner, which is itself triggered by WP-Cron, so on low-traffic sites where WP-Cron rarely fires, queued updates can lag. See Reliable Sync with System Cron to make it dependable.

Controlling Sync Behavior

Disable for Specific Posts

PHP
add_filter('celersearch_should_sync_post', function($should_sync, $post, $index) {
    // Don't sync posts with this meta
    if (get_post_meta($post->ID, 'exclude_from_search', true)) {
        return false;
    }

    // Don't sync draft posts to this index
    if ($post->post_status === 'draft' && $index->get_slug() === 'public-posts') {
        return false;
    }

    return $should_sync;
}, 10, 3);

Watch Additional Meta Keys

By default, only _thumbnail_id changes trigger re-indexing:

PHP
add_filter('celersearch_watch_post_meta_keys', function($keys, $post_id) {
    // Re-index when these meta keys change
    $keys[] = 'custom_field';
    $keys[] = '_price';
    $keys[] = '_product_attributes';

    return $keys;
}, 10, 2);

Disable Real-time Sync Globally

PHP
add_filter('celersearch_real_time_sync_enabled', '__return_false');

Disable Queue System

Forces inline (synchronous) syncing even when Action Scheduler is available:

PHP
add_filter('celersearch_queue_enabled', '__return_false');

Manual Sync

Rebuild Entire Index

From the admin UI, click Rebuild on an index to re-sync all content. From the command line, use wp celersearch reindex — see Creating Indices.

Sync or Delete a Specific Post

Observers expose public wrappers around the sync pipeline:

PHP
use CelerSearch\Factories\IndexFactory;
use CelerSearch\Factories\ObserverFactory;

$index    = IndexFactory::create($index_id);
$observer = ObserverFactory::create_for_index($index);

// Sync the post to the index
$observer->process_sync(get_post($post_id));

// Remove the post from the index
$observer->process_delete(get_post($post_id));

Monitoring the Queue

Check Pending Actions

CelerSearch uses the celersearch Action Scheduler group:

PHP
$pending = as_get_scheduled_actions([
    'group'  => 'celersearch',
    'status' => 'pending',
]);

In Admin

  • CelerSearch → Settings → Sync — shows pending queue actions, with a link through to the full Action Scheduler screen
  • Tools → Scheduled Actions — Action Scheduler's own admin; filter by the celersearch group for low-level inspection

Programmatic access

Recent sync failures are stored by SyncErrorLog so you can surface them elsewhere:

PHP
use CelerSearch\Utilities\SyncErrorLog;

$count  = SyncErrorLog::count();
$recent = SyncErrorLog::get_recent(10);

Each entry records the index, the object ID, the error message, and whether it was a sync or delete failure. Only the most recent failures are kept.

Troubleshooting

Posts Not Syncing

  1. Check if real-time sync is enabled in settings
  2. Verify the post type is in the index configuration
  3. Check celersearch_should_sync_post filter
  4. Check Action Scheduler (Tools → Scheduled Actions, group celersearch) for failed actions
  5. Inspect SyncErrorLog::get_recent() for recorded errors

Sync Too Slow

  1. Increase PHP memory limit
  2. Use a faster search engine instance
  3. Reduce batch size in settings
  4. Check for slow celersearch_searchable_* filters

Duplicate Records

If you see duplicate records after editing:

  1. Content splitting creates multiple records per post
  2. CelerSearch handles cleanup automatically
  3. Run a rebuild if issues persist

Next Steps