The situation

Ilana has sold on Etsy for over ten years and she is very good at it. The Shopify site came later, and it never really caught up.

Three things were wrong at once. The Shopify catalog had drifted to 1,176 products, most of them long since sold or no longer real. The sync app connecting the two stores ran the wrong direction, pushing Shopify at Etsy instead of the other way around, which produced duplicate SKUs. And a lot of listings had no reliable SKU at all, so nothing could be matched between the two stores with confidence.

For a normal retailer that is annoying. For a one-of-a-kind maker it is a real problem. There is exactly one of each hat. If both storefronts sell it, one customer gets a refund and an apology instead of a hat, right before the Derby.

What we did, in order

  • First, agree on a source of truth Etsy is where the business actually lives, so Etsy became the source of truth and Shopify became the secondary storefront. Every decision after this one follows from that. Picking a direction is most of the work in a sync project, and skipping it is why the old setup failed.
  • Give every hat a real SKU I assigned a clean, unique SKU to every active Etsy listing, 411 of them, in a single scheme. Then I verified all 411 against a cross-reference file before touching anything else. Without unique SKUs there is nothing for a sync tool to match on.
  • Back up, then wipe I exported the entire existing Shopify catalog first, 1,176 products and 10,400 rows, and kept the backup. Then I removed the old sync app and cleared the stale catalog. You do not clean up 1,176 bad records one at a time. You keep a copy and start from the good data.
  • Rebuild from the good data I imported the 411 clean listings into Shopify with 3,498 product images attached. Same day. The store went from a catalog nobody trusted to a catalog that matched Etsy exactly.
  • Connect the sync, both directions I connected Trunk between the two stores. It pulled in all 5,771 Etsy listings across every status, active, draft, expired, inactive, and sold out, and the count matched Etsy's own numbers exactly. Then we ran a live two-way sale test the same evening and it passed.
  • Keep it honest with a script, not with eyeballs I wrote a reconciliation script that compares the live Etsy catalog against the live Shopify storefront feed every time it runs. It reports two numbers: active hats missing from the website, and website listings that are still buyable when Etsy says they are gone. That second number is the double-sell risk, stated as a number instead of a worry.

What happened

The migration ran in a single evening on July 3, 2026. The old app came off, the stale catalog came out, 411 clean products went in, and the live two-way sync test passed before the night was over.

1,176 → 411 Shopify products, from a stale catalog to a verified one
411 / 411 active Etsy listings given a clean, unique, verified SKU
5,771 Etsy listings brought under sync, matching Etsy's own count exactly
0 true double-sell risks at the last verified reconciliation

Where these come from: the project's own migration records and the reconciliation script's saved output. The last verified snapshot in the records is dated August 17, 2026, and shows zero active hats missing from the website and zero true double-sell risks. The script gets re-run rather than assumed, which is the whole point of having it.

Since the migration the same process has kept running. A second batch of 108 new listings went through end to end in July. In August a backlog of 579 studio photos became 61 new listings, and every one of the 562 photos that made it into a listing was verified as a pixel match to the original file before the listing went live.

The Hat Doctor online shop showing couture Kentucky Derby hats and fascinators
The shop today: one hat, one count, two storefronts that agree. Visit the shop.

Why this worked

Nothing here was clever. It was order of operations.

Pick a source of truth. Give every item an identifier. Back up before you delete. Rebuild from the clean data instead of repairing the dirty data. Then replace human checking with a script that produces a number, so "is the store correct" has an answer instead of an opinion.

That last part is the piece most small ecommerce operators never get. Two storefronts will always drift. The question is whether you find out from a script or from a customer.

The pattern this fits

This is the multi-channel inventory pattern. It shows up anywhere one business sells the same physical thing in more than one place: Etsy and Shopify, a website and a marketplace, an online store and a register in the shop.

It gets worse the more unique your inventory is. Handmade, vintage, antiques, art, and one-off restoration work are the hardest cases, because you cannot just reorder the thing you accidentally sold twice.

If your stores disagree and you have been fixing it by hand, this is what fixing it properly looks like.