Skip to content

Indexing and sync

Why a product you just added is not in the results yet.

Marutto Search does not query Shopify directly; it keeps its own index. Three mechanisms keep that index from drifting away from the real catalogue.

1. Webhooks — immediately, on every change

Product creation, updates and deletion arrive as Shopify webhooks. This normally lands within seconds.

WebhookKeeps up to date
products/createNew products
products/updateTitle, price, stock, tags and so on
products/deleteRemoved products

Webhooks fire only when something changes. Anything that changed while the app was unreachable never arrives, which is what the next two mechanisms exist for.

2. Drift check — every six hours

Every six hours the index count is compared against Shopify's. If they disagree, the index is rebuilt automatically.

  • No merchant action is required; it runs whether or not anyone opens the admin
  • The check only counts products, so it is cheap — only a shop that has actually drifted pays for a rebuild
  • The admin home shows the last sync time and the result of the comparison

Why this is needed. A full sync only runs when the merchant presses the button; between full syncs the index is maintained by webhooks, and webhooks only fire on change — so anything missed stays missed until somebody notices. In production we found one shop that had gone 49 days without a full sync, and another that had never had one.

3. Full sync

The whole catalogue is re-read when:

  • The merchant presses the sync button in the admin
  • The plan changes — a higher plan indexes more fields
  • The drift check finds a mismatch

On a large catalogue this takes tens of seconds to a few minutes, during which searches report degraded.

What is never indexed

ExcludedWhy
Draft productsNot purchasable on the storefront
Unpublished productsSame
Archived productsSame

A result count lower than the product count in the Shopify admin is usually this.

When degraded is set

degraded_reasonSituation
sync_pendingA first sync, or a rebuild after a plan change, is running
analyzer_mismatchThe store's language and the analyser disagree
search_unavailableA temporary failure in the search infrastructure

Every new store passes through sync_pending on day one. See the FAQ entry.

The set of degraded_reason values will grow. Branch on degraded (the boolean) and keep the reason for display and logs.

Translations

Translations sync separately. Shopify has no webhook for translations at all, so they are maintained by periodic reconciliation only (see Multilingual stores).


Next: Admin controls — changing results without writing code

Marutto Search