Benchmarks / Methodology

How Ottom measures category benchmarks

An Ottom category benchmark is the aggregate of every store Ottom scanned in that category over the trailing 90 days. Each store contributes one observation, its most recent completed scan. The page publishes the middle of that distribution, never an individual store. This page states every rule that produces those figures, so a number you disagree with can be argued with rather than only doubted.

methodology bench-v5 · scoring score-v2 · taxonomy stall-v3

What is measured

Ottom runs an agent through the four stages of a purchase against a real storefront and scores each stage on what the agent actually managed. The overall score is the weighted average of those stages:

Journey stages and their weight in the overall score
StageWhat it asksWeight
DiscoverCan an agent find the store and read its catalogue at all?20%
EvaluateDoes the store’s own data answer what the shopper asked for?25%
CompareCan an agent weigh this store against another on price and shipping?15%
BuyCan an agent get a chosen product all the way to the payment step?40%
Each stage’s share of the overall score, out of 100.

Buy carries the most weight because a store an agent can find but not buy from has failed the thing this measures. The buy stage is scored on how far the agent got, not on how many defects were found: a journey that did not reach the payment step can never score that stage as passing, however tidy the page it stopped on. How one store’s score is made, finding by finding, is on the scoring page.

A stage counts as passing at 80 out of 100. That is the same threshold that stamps PASS on an individual report, so a benchmark and a report never disagree about what passing means. The overall readiness score has no pass mark of its own. A store’s verdict comes from its worst stage, so a store can score well overall and still stall, which is why the score charts draw no line at 80.

Which stores are counted

The all stores benchmark

Alongside the categories, Ottom publishes one benchmark that pools every store it has scanned: every category, and every store whose category could not be determined. It is at /benchmarks/all and it is the figure the benchmarks index opens with.

The platform comparison

/benchmarks/platforms groups the stores in the all stores benchmark by the platform their storefront is built on, as Ottom detected it from markers the platform itself puts in the page, such as its own script paths and response headers.

The segment benchmark

/benchmarks/segments groups the stores in the all stores benchmark by what kind of store they are. Its figures need a free Ottom account, are not open data and are not covered by the CC BY licence on this page. The rules below are public. Rules version segments-v2.

Can AI agents read these stores?

Beside the all stores benchmark, the benchmarks index publishes how often an AI agent is turned away, or finds nothing it can read, at the first step of a scan. It is counted over the same stores as the all stores benchmark, from each store’s latest scan in the window, and it reads findings only, never a score.

Two cohorts, and why the numbers differ

Not every scan reaches checkout. Bot protection, a robots.txt rule that excludes agents, or product pages that could not be read will all stop a scan at the compare stage. That store was measured, and what was found on it is real. What it does not have is a comparable overall score, because the buy stage carries 40% of the weight and an unmeasured stage counts as zero. Its score cannot exceed 60 however good the store is.

Highest possible score with Buy unmeasured: 60 of 100.

So each figure is computed over the cohort it can honestly describe:

Every category page shows both cohort sizes, in that order. Before bench-v2 the two were one number and the score quartiles were computed over both, which understated every category by an amount that varied with how many of its stores had bot protection.

When the scoring changes

The scoring that turns what an agent found into a number is versioned, and it is currently score-v2. A change to it can move a store’s score with nothing about the store changing, so scores from two versions never share a median. When a category’s window holds stores scored under two versions, its scores come from the version most of its stores were scored under, and the rest are left out of the scores. They still count in the stall shares, like a store that stopped before checkout, and the category page says how many were left out.

So a category does not jump the night the scoring changes. It keeps its figures on the old version until more of its stores have been scored under the new one, then moves. Until bench-v4 a category holding two versions published nothing at all, which with a ninety day window meant ninety days of nothing after every change.

Where the stores come from

A category holds two kinds of store, and the difference changes what its figures mean. Some are merchants who came to Ottom and scanned their own storefront. Others Ottom scanned on its own initiative, because a benchmark nobody can fill is not a benchmark.

The surveyed stores are chosen by a rule, not by a list of names. A domain enters the survey if Ottom can read a catalogue of at least 10 products from it, reachable from the fixed egress our agents scan from, robots.txt permitting us. Being well known qualifies nothing.

That rule has a bias, and the bias is in what Ottom can read rather than in what merchants publish. Read it carefully: the test is what we can read, not what a store makes available. Ottom reads a whole catalogue in one request from three places, and three only. Shopify’s products endpoint, the WooCommerce Store API, and a feed a store advertises in its own markup or robots.txt. Every other storefront is read a product page at a time, and that path is capped at 3 pages per scan, so it cannot reach 10 however many products the shop actually sells.

So the threshold is doing something it does not look like it is doing. A storefront on Adobe Commerce, BigCommerce or a custom stack can publish a complete, correct, machine-readable catalogue and still fail to qualify, because we cannot collect enough of it in one pass to compare with the rest. Of the surveyed stores whose catalogue we have been able to read so far, 46 are Shopify and 2 are WooCommerce. That is a fact about our reach, and reporting it as a fact about those platforms would be the more flattering mistake.

The surveyed cohort is therefore not a random or representative sample of online retail, and a median computed over it should not be read as the truth about the category as a whole. It is stated here rather than left to be inferred, because a benchmark whose sampling is undisclosed is a number dressed as a measurement.

This section has been corrected twice. It first described the survey as drawn from a list of recognisable UK retailers, which is how it began; selecting by recognition produced one complete four-stage measurement in ten, because the retailers a person can name are the ones running bot protection and custom storefronts. It then said the rule excluded storefronts that serve no feed for anything to read, which was wrong about the cause: they are read, a page at a time, and it is the page budget that keeps them under the threshold. Both corrections are stated rather than quietly applied, because a sampling rule that changes without saying so is how a benchmark stops being checkable. The stores themselves are not published: a list of names would turn an aggregate study into a report card on individual shops, which is the thing this page exists to avoid.

When a category is published

A category is published only once at least 20 stores in it have been measured at every stage inside the window. Stores whose scan stopped short of checkout do not count toward it, however many there are. This is enforced twice: in the code that builds a snapshot, and as a constraint in the database that rejects the row. It is the rule most likely to be argued away under deadline.

Twenty, specifically, because:

Below the threshold the category page publishes no figure at all, is not indexed, and does not appear in our sitemap or llms.txt. Advertising a URL with nothing behind it is how a placeholder becomes a claim.

How the figures are calculated

How often it refreshes

The pipeline runs nightly and each snapshot covers the trailing 90 days, aligned to UTC. If the pipeline stops, a page keeps serving its last snapshot for 3 days and then stops publishing, rather than serving an indefinitely old figure under a “refreshed nightly” claim. A category that falls back below the threshold returns to saying there is not enough data; its history is kept, not shown.

A surveyed store is measured again at most once every 60 days, so the benchmark stays current. A reading counts for 90 days, and the next one is taken before it leaves the window, so a surveyed store stays in the cohort and its reading is replaced rather than fixed on the day it was first surveyed. It is not continuous monitoring: no surveyed store is visited more often than that. A store that has asked us to stop, that blocks our agents in robots.txt, or that its own merchant has scanned in the last 60 days is not measured again by us. Until 23 September 2026 a surveyed store was scanned once and never again, which is why this paragraph used to say its observation could not be refreshed.

bench-v3 lengthened that window from thirty days to 90, on 20 September 2026. At thirty days, with every surveyed store scanned only once, the arithmetic was self-defeating: a category reached the threshold, then lost its oldest stores a month later with no way to replace them except by scanning new shops faster than the old ones expired. The cost is stated rather than hidden. A 90 day median describes storefronts as they were up to three months ago, so a merchant who fixed something in the second week still appears at their old score until the window carries them out.

What this cannot tell you

Disputing a figure

Every benchmark page shows three things beside its numbers: the cohort size, the window, and the methodology version. Quote those and any figure can be reproduced exactly. If the scan of your own store is what you dispute, your report shows what the agent saw at each step and can be re-run. That is the more useful argument, and the one we would rather have.

Changing any rule on this page changes numbers that have already been published, so it is treated as a versioned event: the methodology version is bumped, the change is stated here, and it is recorded in our decision log. Figures published under an older version keep their own stamp.

Report versions

Every published category report carries a version number, such as v1.2.3. The first number changes when the methodology on this page changes. The second changes when the scoring behind each store’s score changes. The third changes when a nightly refresh changes any figure on the report. A night that leaves every figure the same keeps the version it had.

Earlier versions stay readable at their own address, for example /benchmarks/apparel/v1.2.3, for 90 days after they were issued, with the same figures as JSON beside them. Quote the version with a figure and anyone can check it against the report it came from.

Common questions

Why does my category say there is not enough data?

Because fewer than 20 stores in it have been measured at every stage inside the 90-day window. Below that number a median moves several points when one store re-scans, and a published figure can be worked back to an individual merchant. We publish nothing at all rather than a provisional figure with a caveat next to it, because the caveat is what gets dropped when a number is quoted.

How is my store put in a category?

From what the store publishes about its own products: the product types, the product names and the collection pages. It is a fixed set of rules, not a judgement call and not a model, so the same catalogue always gives the same answer. Where a catalogue does not clearly fall into one of the eight categories, the store is put in none of them rather than in the closest one.

My store is in the wrong category. Can it be changed?

Yes. Write to us and we will set it by hand, and a category set by hand is never overwritten by a later scan. Clearing it removes the store from every benchmark and it stays out.

What is the all stores benchmark?

One benchmark over every store Ottom has scanned, in every category and including stores whose category could not be determined, each counted once. It follows exactly the same rules as a category: at least 20 stores measured at every stage inside the window, medians and quartiles only, and no stall quoted below 5 stores. It is not an average of the category figures. Every store carries the same weight, so a category with more stores in it moves it more.

Does the platform comparison show which platform is better for AI agents?

No. The survey admits a store only if its catalogue can be read in one request, which in practice means Shopify and WooCommerce storefronts, so the platform a store runs on helps decide whether it is counted at all. The comparison describes the stores Ottom could measure on each platform, under the same rules as a category: at least 20 stores measured at every stage per platform, and at least 2 platforms before anything is published. A difference between two platforms is not a verdict on either.

Why do the readability figures not depend on the scoring rules?

Because they read no score. The readability panel counts what the first step of a scan found on each store: a robots.txt rule, bot protection, a missing feed or llms.txt, product pages with no schema.org markup, no shipping costs before checkout. So a change to the scoring rules never moves them. They have their own version rule instead: only stores whose findings were written under the current stall taxonomy are counted. It still needs at least 20 stores. When fewer than 5 stores show something, the exact share is never given. Over a large enough count of stores the panel says only that it is under a whole percent, at most 5%, which is true whether none or 4 of them show it. Otherwise it is withheld.

Which stores are counted?

Every store Ottom has scanned, whether it pays or not, counted once each. A category benchmark counts the stores that carry that category; the all stores benchmark counts every one of them, including stores with no category. A merchant who re-scans their own storefront five times in the window contributes once, and contributes their most recent scan, so nobody can move their own category by repeating a scan. Stores Ottom surveyed are measured again at most once every 60 days, so their reading is replaced before the window carries it out and the benchmark stays current. A store whose owner has asked Ottom to stop scanning it leaves every figure at the next nightly refresh.

Why does a category page show two different store counts?

Because two different questions have two different answers. The score quartiles come from the stores measured at every stage of the journey. The stall figures come from every store scanned, including the ones stopped early by bot protection or a robots.txt rule. A store stopped before checkout has no comparable overall score, since the buy stage is 40% of the weight and an unmeasured stage counts as zero, but it is still the clearest evidence there is about the stall that stopped it.

Are these stores a representative sample of the category?

No, and the figures should be read accordingly. Some stores are merchants who scanned their own storefront. The rest Ottom surveyed on its own initiative, and a store enters that survey only if Ottom can read a catalogue of at least ten products from it in one request. In practice that means Shopify and WooCommerce storefronts: everything else is read a page at a time, which is capped well below ten, so it cannot qualify however much it publishes. A category median here therefore describes the storefronts we can read in bulk rather than the category as a whole.

Is my store identifiable from a benchmark page?

No. Benchmark pages carry aggregates only: quartiles rather than a best and worst store, whole-percent shares, and no store name, URL, or identifier anywhere in the data. A stall found on fewer than 5 stores in a category is withheld and counted in a "withheld" total instead, because at that count it points at a merchant rather than at a category.

Why a median rather than an average?

An average is moved by one extreme store, and in a cohort of a few dozen that store is identifiable by anyone who can see the average move. The median and the quartiles describe the middle of a category, which is what a merchant asking "is this normal?" actually wants.

The number is wrong. How do I dispute it?

Every benchmark page shows the cohort size, the window it was counted over, and the methodology version that produced it. Quote those three and we can reproduce the figure exactly. If the scan of your own store is what you dispute, that is a different and more useful conversation: your report lists what the agent saw at each step, and you can re-run it.

How often do the numbers change?

The pipeline runs nightly and each snapshot covers the trailing 90 days, so a category moves gradually rather than jumping. If a category drops back below 20 stores, its page stops publishing figures and returns to saying there is not enough data; the history is kept but not shown.

Read next

Run a scan on your own store