The sync engine

How catalogue repricing is scheduled, batched, resumed and finished — and what each job state actually means.

Updated August 2, 2026

Repricing a catalogue is the cost Price Anchor pays for having a fast storefront. The engine is built so that cost is bounded, resumable and visible.

Scheduling

Price Anchor uses Action Scheduler when WooCommerce provides it and falls back to WP-Cron when it does not. Both are hidden behind one interface, so nothing in the pricing code cares which is running. Action Scheduler is detected as a capability, never required as a dependency.

Batching and resumability

  • Work is processed in batches using keyset pagination — the job stores a cursor rather than an offset, so inserting or deleting products mid-pass cannot cause it to skip or repeat rows.
  • Job state — id, cursor, totals, status — is persisted. If a request dies halfway, the next batch continues from the stored cursor instead of starting over.
  • A lock prevents two passes running at once. Two workers repricing the same catalogue simultaneously is exactly how you get inconsistent prices.
  • Batch size is filterable for stores with unusual hosting constraints.

Job states

State Meaning
Idle No pass in progress. This is the normal resting state.
Queued A pass has been requested but background processing has not picked it up yet.
Running Batches are being processed. Progress is shown.
Done Every product in scope has been repriced.
Failed The pass stopped on an error. The reason is in the WooCommerce log.

The state set is closed, so a corrupted row cannot invent a state the UI does not know how to render.

Completion

A batch that reaches the job’s total, or returns fewer rows than its limit, has proved there is no required next page. The worker that processes that terminal batch commits Done immediately. Earlier behaviour persisted “running” and scheduled an empty follow-up batch, which made completion depend on another cron tick and left a one-product store sitting at “100% Running” with a Cancel button visible after every price was already current.

When a pass starts

  • A validated new rate table is stored.
  • A pricing-relevant setting changes: markup, rounding, source currency or provider.
  • The WooCommerce store currency changes.
  • You press the manual resync control on the Sync tab.

Saving an individual product reprices that product immediately rather than queueing a whole catalogue pass.

Large catalogues

The engine is designed to be boring at scale, but a first run over tens of thousands of variations is still real work. If your host is aggressive about long-running requests:

  • make sure Action Scheduler is available — WooCommerce ships it, so this usually means confirming it is not disabled;
  • run the first pass outside peak hours;
  • confirm real cron is firing. A low-traffic site relying on WP-Cron’s page-view trigger will reprice slowly simply because nobody is visiting.