Methodology
How we collect and compare grocery prices
Where the prices come from, what the dates mean and how we compare the same grocery items each week.
How we collect prices
We schedule price collection from Canadian grocery listings every night. The current collection began March 22, 2026. We track 82 stores across 18 grocery chains, with counts checked October 23, 2026. We also check extra stores less often, with varying start dates.
Our earlier collection has stored prices dated December 11, 2025 through March 21, 2026. It used different stores and product records. These dates do not establish a price for every day or store. Keep the earlier and current collections separate when studying changes over time.
See the chains and stores we track and sample prices and column descriptions.
What a price means
- Each price belongs with its product, chain, store and date. A price recorded at one store does not establish the price at every location that chain operates.
- A missing date means we did not record a price. It does not mean the price stayed the same. We leave those gaps in the data.
- Product codes belong to each chain. A barcode can help compare products across chains when one is available; the package size and description still need checking.
- Compare the same pack size and price unit. A case of bottles and a single bottle are different purchases; meat sold by weight needs a comparable weight or unit price.
- Sale information varies by chain and date. A missing sale label does not prove that the price was a regular price. Check the sale fields for the period you plan to study.
How the index works
Each week, we compare items priced at the same stores in both weeks, normally comparing with the previous week. We calculate each price change and average those changes. Items missing from either week are left out, so adding or losing a product does not count as a price change.
We publish a new reading after the week ends, when there are enough prices to compare. If there are too few prices, the chart holds its last value and marks that week as having no new reading. After a gap, a change covering several weeks is labelled with that period rather than presented as a one-week move.
Read the free weekly index or check a week's figures.
What it isn't
This is a measure of listed grocery prices at the stores we track. It is not Statistics Canada's Consumer Price Index: it does not weight items by household spending or adjust for changes in product quality.
A listed price does not tell us how many units shoppers bought, how much they spent or why a retailer changed its price. The data does not cover every Canadian grocery store. Costco is not included.
Corrections
When we find a mistake in a published coverage statement, we correct it here and keep the correction visible.
- Metro and Food Basics. The collection pause beginning September 4, 2026 remains part of the record. Both chains are collecting again in Ontario, checked October 23, 2026. The old Metro entry in British Columbia is no longer included.
- Longo's and Farm Boy. We previously described these prices as having continuous weekly history from late March 2026. Both had a collection pause across April and May 2026. Check the dates in the data before using either for a comparison over that period.
- Longo's and Farm Boy prices describe each chain in a Toronto-area postal market, rather than separately checked physical stores.
- Individual products can have missing dates even during weeks when we collected other prices, because flyer contents change.
When citing Vynn, name the series, the week or dates used, the method version and the date you accessed it.
Technical detail for researchers
Collection systems and identifiers
The earlier system is historical_v1, with stored positive-price event dates from 2025-12-11 through 2026-03-21. The current system is current_v2, beginning 2026-03-22. This is a date span, not evidence of daily continuity. store_id and store_id_v1 belong to different systems and must not be joined across them.
Reference stores form the core panel, with one banner-province pair each; additional satellite stores have varying collection frequencies and start dates. The current published count includes active reference stores with observations_30d > 0 at the materializer's last computation. A store that stopped collecting within that window can still count. It does not establish successful collection on every night. Panel counts were checked 2026-10-23 19:35 UTC; catalogue and price totals were checked 2026-10-23 19:35 UTC.
external_sku identifies a product within a banner. UPCs can support cross-retailer matching where present, but do not establish that every SKU is matched. Pack counts, random-weight products and unit-price bases require separate comparability checks.
Current-system observations pass an automated price guard before acceptance; only accepted observations are published. Passing the guard does not establish product comparability.
Promotion classification
Promotion classification is not a comparable series across the whole history. A reliable start date across all chains has not been established. The introduction of a retailer sale marker does not, by itself, establish that date. unknown means a record was collected but not classified; it is not evidence of a regular price.
Index calculation
The Vynn Canadian Grocery Price Index is a chained, matched-model Jevons index computed over reference stores, joined at event time to the designation in force when each price was observed , a later panel change (a store failover, a re-designation) never rewrites published history.
- Each link joins a week to the most recent preceding week that had usable observations , normally the week before, but longer across a collection gap. Only items priced in both of those weeks contribute. This is the “matched model”: it prevents a change in which products happened to be collected from registering as a price change.
- Links are therefore between consecutive measured weeks, not necessarily consecutive ISO weeks.
weeks_spannedrecords the real calendar separation, so a multi-week link is never mistaken for a one-week move. - The link between two weeks is the geometric mean of price relatives across matched items. Geometric rather than arithmetic, so a price and its reversal cancel exactly.
- Links are chained onto a running index. The base week is 100.
- An item is keyed by banner, store and SKU, so the same product at two retailers, or at two stores of one banner, is two items. Neither a price difference between retailers nor a change in geographic sample composition is ever read as a price change.
- Only closed ISO weeks aggregate. The in-progress week is mid-collection by construction, so it publishes no measurement and reports carried-forward instead of a value that would drift as batches land.
- The base seats at the first week with at least the minimum matched items: a thin first week cannot become the permanent base, and with no adequate week the series is reported unavailable rather than a flat 100.
- A week with fewer than 30 matched items is suppressed, not published: the previous value is carried forward and the point is flagged
carried_forward. - A week with no usable observations publishes no measurement. It carries the previous value, is flagged, and does not become the base of the next link. The series always has one point per calendar week, so week-over-week and year-over-year offsets mean what they say.
- When a link spans a gap,
weeks_spannedreports the real interval and the week-over-week figure is withheld , a multi-week move is not a one-week move.
What this is not. It is not an official consumer price index. It is not weighted by expenditure share, and it is not adjusted for quality change. It is a transparent, reproducible measure of observed shelf prices across a defined panel.