Concepts

Recipes

A recipe is one recommendation rule: one algorithm plus a set of parameters. You create recipes at Project → Commerce → Recommendations. A project can have as many recipes as you need: one for bestsellers, another for viewed-together on product pages, another for trending per category.

Each recipe runs independently on its own schedule and produces its own output dataset.

The six algorithms

Bestsellers

Products ranked by units sold across all orders, over a rolling window (default: 28 days). Optional per-category mode produces separate lists for each product category alongside the global list. Use this on your homepage, empty search pages, or anywhere you need a safe, broadly-useful set of products.

Products ranked by the ratio of recent sales (last 7 days) to their baseline rate (prior 28 days). A product climbing fast scores higher than one that is merely popular. For example, a product that jumps from 10 units a week to 40 units this week outranks one steadily selling 200 units a week with no change. A minimum-support threshold (default: 3 units) keeps low-volume items out of the results. Use this for "what's hot right now" placements.

New arrivals

Products from your Live Catalog sorted newest first by each product's source createdAt (falling back to the time A vs B first saw the product). No order data is needed: this algorithm reads only the catalog. Use this on dedicated new-arrivals pages or to surface recently launched products.

Viewed together

Products that the same visitor viewed during the same browsing session, aggregated across all visitors. For a given seed product, the output is the products most commonly viewed alongside it. Requires product-view event data: either from the Shopify pixel (shopify:product_viewed) or a product_view custom event metric you fire on product pages. Use this on product detail pages to show what other visitors browsed.

Bought together

Products that appear together in the same orders, aggregated across all orders. For a given seed product, the output is the products most commonly purchased alongside it. Requires order data from either the Shopify integration or the purchase tracking from the revenue phase. Use this for "frequently bought together" or post-add-to-cart placements.

Similar products

Products whose catalog text (title and description) reads most similarly to the seed product's. Unlike the behavior-based algorithms, this one needs no shopper traffic or order history at all: it works from your Live Catalog alone, so it produces full results from day one. Use it on product detail pages, out-of-stock pages, or as a fallback for behavior-based recipes on products with no history yet. See the Similar Products page for the full story.

Which algorithm should I start with?

Bestsellers, Trending, Viewed together, and Bought together all need real traffic or order history before they produce any output (see the cold-start floor in Reference). On a brand-new store, start with Similar products or New arrivals instead: both read only your Live Catalog, so they work from day one.

Outputs are datasets

When a recipe runs, it does not write to a separate recommendation store. It writes its output directly into a system-managed A vs B dataset: a FEED-type dataset created automatically when you create the recipe. This dataset appears on the Datasets page with source SYSTEM and type FEED.

Because the output is a standard dataset, everything you already know about datasets applies:

  • Versioning: every run creates a new dataset version. The engine activates the new version atomically when the run succeeds.
  • Rollback: if a run produces bad results, roll back to a previous version the same way you would for any other dataset.
  • Reading: use avsb.dataset(slug) in the snippet, client.datasets.get(slug, key) in the Node SDK, or the lookup API. See Serving & Reading Datasets.
  • A/B testing: pit recipes against each other (or against a no-recommendations holdout) by calling a different recipe per variation with the recs API. See the Recommendations Quickstart.

A failed run never overwrites the previous version. If the run fails, the previous output keeps serving. The Recommendations page shows the run outcome and stats.

The output feed ID

The feed ID is generated from the recipe name when you create the recipe. It starts with rec-, so a recipe named "Homepage bestsellers" gets a feed ID like rec-homepage-bestsellers. You can see the exact feed ID on the Datasets page or in the recipe's detail view.

Row keys

How the engine keys its output rows depends on the algorithm:

AlgorithmKey per rowExample keys
Bestsellers, Trending_global for the site-wide list; cat:{category} when per-category is on_global, cat:footwear
New arrivals_global for the site-wide list; cat:{category} when per-category is on_global, cat:accessories
Viewed together, Bought together, Similar productsThe seed product's SKUSHIRT123, SHOE456

For seed-based algorithms (viewed/bought together, similar products), you look up the seed product's SKU to get its list. For list algorithms (bestsellers, trending, new arrivals), you look up _global or a category key.

The Live Catalog

Every recipe reads from your project's Live Catalog: the single, always-fresh copy of your products. The recommended way to populate it is with a server-side source (Shopify, a product feed, the Push API, or an upload) so every product is available regardless of shopper traffic. You can optionally collect live product data from your storefront as shoppers browse, for real-time price freshness. See Connect your catalog. You do not pick or link a "catalog dataset" per recipe; every recipe automatically uses the one Live Catalog for your project.

The engine uses the catalog two ways:

  • As a data source. For full scans (denormalising rows, ranking New arrivals by recency, comparing text for Similar products) the engine reads a snapshot of the whole catalog.
  • As live enrichment. When a recipe writes its output, each item carries product details (title, image, href, category) baked in. But price, availability, and stock are not baked in: they resolve fresh.

SKUs that are not in your Live Catalog are dropped from results at build time, never returned as empty cards. The run stats report how many items were dropped this way: see droppedNoCatalog below.

Price and stock resolve live, at serve time

The ranking is baked nightly, but the display fields that change often (price, compare-at price, availability, stock, and image) are resolved fresh from the Live Catalog at the moment a recommendation is served, then overlaid onto the nightly rows. A price you change in your store, or a product that sells out, shows up within the edge-cache window (about a minute): no nightly rebuild and no dataset republish needed. See the Reference page.

Two algorithms lean on the catalog as their only data source, not just for enrichment:

  • New arrivals sorts products by each product's source createdAt (falling back to when A vs B first saw the product).
  • Similar products reads title and description (the text it matches on), plus the optional category and stock signals used by its filters. See Similar Products.

Coverage: what droppedNoCatalog means

During each recipe build, the engine checks every candidate item against your Live Catalog. Items that do not have a matching catalog row are dropped and never written to the output: a recommendation can only be served if A vs B has product data for it.

The count of dropped items is stored as droppedNoCatalog in the recipe's run stats. You can see it on the recipe detail page after each run.

The project-level roll-up of coverage (droppedNoCatalog summed across all enabled recipes) is shown on the Product catalog page as a percentage: "X% of the items your recipes recommend have live catalog data". A low coverage percentage means your Live Catalog is missing SKUs that your order or browsing data references. Adding those SKUs to the catalog (via Shopify, Push API, feed, or upload) brings coverage up and ensures those items can actually be recommended.

Fallback chains

A fallback chain is an ordered list of recipes or datasets (up to four steps) that the engine tries when a lookup for a given key finds no result. For example, if viewed-together has no data for a seed SKU (because that product was viewed alone), the chain can fall through to bestsellers so the user always sees something.

You configure fallback chains on the recipe's detail page using a drag-and-drop list. The chain is stored with the recipe and walked at serve time by the recs API: when the primary output has no row for the seed, the chain is tried in order until a step can serve.

Where fallback resolution happens

Fallback chains are resolved by avsb.recs.get() (and client.recs.get() in the Node SDK). Direct dataset reads (avsb.dataset(), client.datasets.get(), or the lookup API) read only the one dataset you ask for and do not walk the chain, so handle found: false yourself on that path.

Was this helpful?