logo
How BPS Cloud Prevents Duplicate Products When a Sync Job Fails Mid-Run

How BPS Cloud Prevents Duplicate Products When a Sync Job Fails Mid-Run

Large syncs don't run as one atomic operation — they're broken into chunks, processed in parallel, and retried automatically if something goes wrong partway through. That's good for reliability, but it raises an obvious question: if a chunk fails halfway and gets retried, does it redo work it already finished? For rows matched by SKU, a repeat is harmless. For rows creating a brand-new product with no SKU yet, a naive retry would create it twice. Here's how BPS Cloud rules that out.

Why retries happen at all

Sync jobs are queued and processed by chunk, and the queue is configured to redeliver a chunk up to three times if it fails before finishing. That's a deliberate safety net — a chunk can die from a transient network blip or a Lambda timeout, and redelivery means the job still completes instead of silently losing that batch of rows. But redelivery replays the whole chunk, including any store writes it already made before it died.

The risk this creates

For update rows — matched by id, a stored row-link, or an exact SKU — a repeat is safe. Sending the same price or stock value twice produces the same end state either time. But for rows with no SKU that are creating a new product, replaying the chunk means calling "create" twice, which WooCommerce will happily do: two identical products, one job. That's precisely the class of bug the matching engine exists to prevent, just arriving from a different direction (a queue retry instead of a bad match).

How it's closed off

Each chunk writes a completion marker in the job's own record the moment it finishes — results persisted and counters finalized. Before a chunk does any store writes, it checks for that marker first. If the marker's already there, the chunk is skipped entirely: no repeat WooCommerce calls, no duplicate rows, no changed counters. We verified this directly rather than just trusting the logic — ran a real job to completion, then manually replayed the exact same chunk message to simulate a queue redelivery. The worker logged that the chunk was already done and skipped it, with zero additional store writes.

What's still an edge case, honestly

There's one narrow window this doesn't fully close: if a chunk dies between a successful WooCommerce write and that completion marker being saved, a retry would still replay that specific write. For SKU-based rows this self-heals anyway — the retry looks the product up by SKU, finds the one it just created, and updates it instead of creating a second. Only SKU-less create rows in that exact timing window remain exposed, and we haven't seen evidence it's happening in practice. A fully airtight fix would need WooCommerce itself to accept a client-side idempotency key on create — a bigger change we're not making without a real case showing it's needed.

Try it

BPS Cloud is free to install from the Google Workspace Marketplace. For the matching rules this builds on, see why we rebuilt SKU matching from scratch and 5 bulk-editing mistakes that create duplicate products.

Prefer the WordPress plugin? See the Bulk Product Sync plugin page for pricing and details.