← Back to writing
Writing · migration

The Migration Number Nobody Reconciles

By Leo Nguyen · Sep 24, 2026 · 4 min read
The Migration Number Nobody Reconciles
Jump to section

Most replatforming post-mortems are about the theme. The ones that actually hurt are about counts — the products, variants and customers that quietly didn't arrive, and that nobody looked for until a buyer did.

On a recent PrestaShop → Shopify migration for a European fashion store — roughly 4,000 products, tens of thousands of customers — the first import looked fine. The dev store loaded, the homepage rendered, the collections were there. Then we counted.

#"Imported successfully" is not a number

The import tool reports success when it finishes writing rows. It does not tell you how many rows it was supposed to write. Those are two different facts, and the gap between them is where migrations rot.

Here is what the counts actually said on that first pass:

  • Products: 3,477 of 4,173 landed on the dev store. 696 missing — about one in six, gone without an error.
  • Active vs archived: of what did land, 2,078 were archived against 1,399 active. A catalog that reads as "mostly hidden" to a shopper and to an AI agent — even though the products exist.
  • Customers: 4,065 of 27,878. That is −85%. Not a rounding gap. An import that, left alone, would have launched a store that had forgotten most of the people who ever bought from it.

None of that surfaced in the storefront. You cannot eyeball 696 missing products across 4,000. You certainly cannot eyeball a customer table you never see. The only thing that catches it is a count.

#The reconciliation gate

Before a migrated store is allowed anywhere near cutover, it passes one gate: a script that counts the source and the destination for every object that migrated, and prints the delta.

  1. Count both sides, per object. Products, variants, images, customers, orders. Source system and destination store, same query, same day.
  2. Print the delta, not the total. "3,477 / 4,173 (−696)" is a finding. "3,477 imported" is a press release. The delta is the number a human has to sign off on.
  3. Split archived from active. A product that imported as archived is not a win. Count status, not just existence — an AI shopping agent reads an archived PDP as unavailable.
  4. Explain every gap or fix it. −696 products might be intentional (discontinued lines the client asked to drop) or a broken CSV column. Either way, someone writes down which, by SKU range. Silence is not an explanation.
  5. Write a clean-or-dirty verdict. One sentence, signed: the migrated store is clean, or it is dirty and here is the list. No verdict, no cutover.

#Why this is an AI-visibility problem too, not just a data problem

A store that launches with 85% of its customers missing loses the lifecycle list — the abandoned-cart, the win-back, the segment history. But it also launches with a catalog where two-thirds of products are archived, and archived products are invisible to the AI shopping agents now reading storefronts on a buyer's behalf. The reconciliation gate protects the numbers the business runs on and the surface the buyer's assistant sees. They fail together, and they're caught by the same count.

#The rule

Treat the import tool's "success" as a claim, not a result. The result is the delta, and the delta is what a human signs. Count both sides, per object, before anyone types the word cutover.


Send one store URL and we'll run a free async AI-correctness read: we ask live AI agents about your products, check which ones they see as available, and send back a named punch-list of exactly where your catalog is invisible or misread — and, mid-migration, whether the numbers reconcile before cutover: luma-e.com/ai-readiness. No call required.

Frequently asked
Doesn't the import tool tell me if products failed?
It reports rows written, not rows expected. A silent gap — a broken CSV column, a filtered status — finishes as "success". Only a source-vs-destination count catches it.
What objects should I reconcile?
Products, variants, images, customers and orders at minimum — count each on both systems, same day, and record the delta per object.
Why does archived-vs-active matter for AI visibility?
AI shopping agents read an archived product page as unavailable. A catalog that imports "mostly archived" is invisible to agents even though the data exists.
When should reconciliation run?
Before cutover, as a hard gate — a signed clean-or-dirty verdict. If there's no verdict, the store isn't ready to launch.
NEWSLETTER

More like this, only when it's worth it

Occasional email on AI x ecommerce - how agents read stores, what breaks, what we shipped. No weekly filler.

No spam, no sequence-drip. Unsubscribe anytime.