All postsProduct·MAY 19, 2026·6 min read

Catalog sync, rebuilt around Shopify's scale patterns

We re-architected PlainSaid's catalog sync around Shopify's two scale primitives: the Bulk Operations API for initial backfills and webhook subscriptions for ongoing changes. Here's what shipped and what it means for premium DTC brands.


Source · PlainSaid product release

Today we shipped a re-architected catalog sync inside PlainSaid, built around the two primitives Shopify recommends for catalog data at scale: the Bulk Operations API for initial backfills, and webhook subscriptions for ongoing changes. The merchant-facing result is simple — PlainSaid now ingests catalogs of any size cleanly, and stays current automatically once installed.

This was the right moment to make this move. PlainSaid is now live on the Shopify App Store, and the brands we want to serve — premium DTC merchants in furniture, supplements, apparel, and beauty — frequently carry catalogs in the 1,000 to 25,000-product range. Aligning early with Shopify's scale patterns means that whether a brand has 200 products or 100,000, the install experience feels the same.

Here's what shipped and why.


The two Shopify-recommended scale primitives

Shopify's platform docs give clear guidance on how apps should ingest and stay current with merchant catalog data. The recommended shape has two halves.

For initial backfill: the Bulk Operations API.

Rather than paginating through products GraphQL queries client-side and managing per-page state, an app submits a single bulk query. Shopify runs it server-side, generates a JSONL file with the full result, and notifies the app when it's ready. The app downloads the file and processes it locally. There's no pagination state to track, no per-page round trips, and no HTTP-timeout exposure during the heavy work — the heavy work happens inside Shopify.

This is purpose-built for the "I just installed and need to see my whole catalog" moment. Any merchant, any catalog size, single click.

For ongoing changes: webhook subscriptions.

Rather than asking merchants to remember to "sync" when something changes, an app subscribes to products/create, products/update, and products/delete webhooks. Shopify pushes diffs to the app as merchants make changes in their admin. The app's local mirror stays current in near-real-time without anyone clicking anything.

This is purpose-built for the "I just edited a product, will PlainSaid see it?" moment. The answer becomes immediate yes, with no action required.


What changed inside PlainSaid

We adopted both patterns this week, in three focused commits.

Webhook-driven incremental sync. We extended our existing products/update and products/delete webhook handlers to keep PlainSaid's local product mirror current alongside the knowledge-base staleness tracking that was already there. We added a new products/create subscription so newly published products land in PlainSaid the moment they're created in Shopify. Once a brand is installed, their catalog stays current automatically — no manual sync needed for steady-state changes.

Bulk Operations for initial backfill. The "Sync catalog" action in the admin now kicks off a Shopify Bulk Operations query. Shopify generates a JSONL snapshot of the brand's full catalog server-side; the PlainSaid admin shows a live progress indicator as the snapshot is being prepared, then as the products land. The same flow handles a 200-product Starter brand and a 25,000-product Scale brand identically.

A small state-tracking table. A new BulkSync table inside PlainSaid records every initial-backfill run — when it started, when Shopify finished, when our processor completed, the final product count, and any error code. This is a quiet piece of infrastructure that lets us answer "did the sync work?" with data rather than vibes, and it'll feed the per-brand reliability tracking we'll surface in the Insights dashboard later this quarter.


What this means for the brands using PlainSaid

If you're a merchant evaluating PlainSaid or already using it, here's the practical shape:

Install day. Click install, pick a plan, click "Sync catalog" once. PlainSaid shows a progress indicator while Shopify prepares your catalog snapshot, then as your products land in the PlainSaid admin. For most brands this takes under a minute. For very large catalogs it takes a few minutes — still one click, still no babysitting.

Day two onward. You don't click "Sync catalog" again. When you add a product in Shopify, it shows up in PlainSaid within seconds. When you edit a product description, PlainSaid notices and marks the related knowledge-base entries as worth a fresh look. When you delete a product, PlainSaid cleans up the corresponding entries. The button is still there as a "force a full re-sync" escape hatch for the rare moments you want one, but the steady-state experience is "PlainSaid just knows."

Plan limits, unchanged. The Starter / Growth / Scale plan caps on product count still apply the same way they did before — we count toward your plan's limit during sync, and the limit is enforced cleanly whether the sync came from Bulk Operations or from a webhook. Nothing about the pricing structure changes here.

Storefront widget behavior, unchanged. This release is entirely about how PlainSaid ingests and tracks catalog data on our side. The shopper-facing widget that answers questions on your product pages, the brand-voice grounding, the JSON-LD publishing layer — none of that changes. This is plumbing, done well.


Why this matters specifically for premium DTC

The brands we built PlainSaid for tend to carry mid-market catalogs — not the 50-SKU artisanal boutique, not the 500,000-SKU marketplace, but the 1,000 to 25,000-product premium brand that has invested years of editorial work in their product descriptions and treats their catalog as a brand artifact.

For brands in that range, two things matter that don't get talked about enough:

The "I just installed" first impression has to be smooth. A merchant who clicks install and waits, then waits, then refreshes, then waits — they've already started forming the opinion that the app isn't ready for their scale. Smooth ingestion of a real catalog on install day is table-stakes for any app that wants to serve serious brands.

The "I just edited a product" feedback loop has to be tight. Merchants iterate on their catalog constantly — adding products, tightening descriptions, retiring lines. An app that requires them to remember to click "sync" after every change becomes friction, then becomes forgotten, then becomes stale. Webhook-driven incremental sync makes the question "is PlainSaid current?" answer itself.

Both of these are the kind of thing that's invisible when it works and immediately obvious when it doesn't.


The shape of the work

Three commits, isolated by responsibility, each one independently rollback-able:

  1. Webhook handlers + new products/create subscription. Surgical changes to existing routes, plus one new file. Zero schema impact.
  2. BulkSync Prisma migration. Single new table, purely additive, no changes to any existing column on any existing table. Migration includes inline rollback SQL — the discipline matters more than the change is large.
  3. Bulk Operations service + route refactor + admin UI. The biggest piece, but cleanly separated from the schema commit so either can be reverted on its own without disturbing the other.

This is the engineering pattern we've been encoding in our internal release-process discipline: high-risk schema changes ship in their own commit with inline rollback steps, behavioral changes ship in adjacent commits, and the whole sequence is reviewable as a story. We wrote this approach up internally last week (graduated by merchant count, not by feel) — this release was the first real test of the discipline, and it held up cleanly.


What's next

This release is one of several "we're now operating at the scale a premium DTC brand expects" upgrades you'll see from us over the coming weeks. Next on the list:

  • The Insights dashboard. Per-brand visibility into how PlainSaid is performing in your store — widget engagement, answer confidence rate, the questions shoppers actually asked, the gaps worth filling. Designed to be the artifact you forward to your leadership when they ask "is this working?"
  • The four-pillar measurement layer. Behind the dashboard, a quietly comprehensive way to triangulate PlainSaid's impact across our own platform data, your Shopify analytics, AI search visibility, and merchant voice. Without it, we can't write the case studies that actually convince other brands. With it, we can.
  • First case study. The plumbing now in place to make the first one credible. We'll publish when we have at least 30 days of real data and the merchant's enthusiastic green light.

Each of those is its own post when it ships.

For now, the catalog sync is the foundation everything else sits on top of. We're glad to have it built the way Shopify's docs say to build it — because that's the way it'll keep working as brands grow.

If you're a premium DTC brand and want to see what PlainSaid does to your product pages, the App Store listing is the fastest path: apps.shopify.com/plainsaid. Install, sync, and the widget is live on your PDPs within a few minutes.

By PlainSaid · MAY 19, 2026