DishMark

How the figures are produced, and what we refuse to do.

Published in full, because a benchmark is only as good as the method behind it. If you disagree with a convention here, you can see exactly which figure it affects.

Discovering establishments

Search areas resolve against a gazetteer of every UK settlement and postcode district, so any town or village can be searched rather than a curated shortlist of larger places.

Candidate establishments come from complementary sources. The Food Standards Agency food hygiene rating register is the authoritative list of registered UK food businesses, which gives completeness. OpenStreetMap provides the website a menu can actually be read from, which is the field that decides whether an establishment can be reported on at all. Records are merged on identity — a provider identifier where one exists, otherwise a similar name within about 120 metres — so the same physical venue reported by several sources appears once.

Volume is counted as unique canonical venue locations whose menu collection is attempted, including unsuccessful attempts. A venue we check but cannot read still consumed the work, and is reported as such.

Locating menus

We read public menu pages and PDF menus one level deep from each establishment’s own website, plus delivery-marketplace listings where the establishment appears on one. Known menu URLs are reused rather than rediscovered. Where no menu URL is known, we follow menu-shaped links from the homepage before trying conventional paths.

robots.txt is fetched, parsed and respected, including crawl-delay. Requests are rate-limited per host, and a host returning 429 is backed off rather than retried. An establishment that excludes us is recorded as “source unavailable to us” in the coverage funnel — not quietly dropped.

Extracting prices

Extraction runs in tiers, cheapest and most reliable first. Where an establishment publishes schema.org menu markup, we read it directly: it is structured data the publisher stated, so nothing is inferred. Failing that, a deterministic parser reads name and price pairs from the page’s tables, lists and item containers, tracking the menu section each item sits under. Only pages that defeat both are passed to a language model for transcription, and its output is held to a lower confidence and the same plausibility checks.

Every candidate price must carry a currency signal or decimal pence to be trusted, and must fall in a plausible band. Delivery charges, service charges, minimum order values, deposits and gift cards are rejected.

DishMark does not invent missing prices or menu items. If an establishment does not publish a price, it is absent from the figures and counted in the funnel. There is no interpolation and no modelled fill.

Canonicalising dishes

Raw menu text is mapped to a canonical dish and portion so that “Cod & chips (reg)” and “regular cod and chips” benchmark together. Resolution is cached per distinct phrasing across the whole index, and near-matches are resolved by trigram similarity and written back, so the index learns the long tail of menu phrasing over time. An item we cannot confidently map is still stored with its raw name; it simply does not enter a benchmark.

Calculating the figures

We report minimum, 25th percentile, median, 75th percentile and maximum, with both the observation count and the distinct-establishment count.

The default statistic uses one median comparable price per establishment, per dish and per service channel. This stops an establishment that lists a dish in six sizes from outweighing one that lists it once. Item-weighted figures are available in the data workbook for anyone who wants them.

Quantiles use inclusive linear interpolation, applied identically across the portal, the PDF, the workbook and the CSV. Outliers beyond 1.5× the interquartile range are flagged and retained, never removed: a £40 fish and chips is usually a sharing platter, and you need to see it to judge.

Measuring trends

Price series are built over a matched panel: only establishments observed across most of the window contribute. This matters more than it sounds. If a venue enters the index halfway through a year, its prices would shift the median on arrival and read as a market movement that never happened. Holding the panel constant is the only way a trend line means what a reader will assume it means.

A month is reported only where enough distinct establishments were observed for a median to carry information. A line tracked at two venues is noise, and drawing it would imply a precision the data does not have.

Detecting change

Change is matched within establishment, service channel, dish, portion and menu type. Absence from a failed refresh is never treated as item removal, and a closure is only ever reported as “suspected”, after repeated failed refreshes. A timeout is not evidence that a dish was withdrawn or a pub shut.

Evidence and dates

Every reportable observation carries a source URL, a timestamp and an evidence locator naming the menu section and line. The retrieval date is recorded separately from any publication date printed on the menu itself, because the two are frequently different and conflating them would overstate freshness.

What we do not do

We do not measure items sold, customer demand or financial performance. We do not infer allergens — allergen information is a legal obligation of the establishment and must come from them. We do not estimate popularity from menu placement. We do not publish an establishment’s data under a claim of completeness we cannot support.

Conventions at a glance
Volume
Unique canonical venue locations whose collection is attempted, including failures
Default statistic
One median comparable price per establishment, dish and channel
Quantiles
Inclusive linear interpolation, one convention everywhere
Outliers
Beyond 1.5× IQR — flagged, retained
Minimum sample
Three distinct establishments before a range is reported
Change matching
Establishment × channel × dish × portion × menu type
Failed refresh
Never treated as removal or closure
Dates
Retrieval date recorded separately from menu publication date
Trends
Matched panel of establishments observed across the window
Own-price comparison
Your sites excluded from the market figures
Place names
GeoNames (CC BY 4.0) — every UK settlement and postcode district
Check any figure yourself
Every report exports an audit JSON file containing each observation with its source and timestamp. See a sample report.