Index methodology

From shelf price
to price index.

A weekly grocery price index computed from a fixed 50-item basket priced across 21 retailer banners and 13 Canadian cities. The headline index and the nine category sub-indices are one estimator: a direct fixed-base, matched-model weighted Jevons index (methodology v2) with the week of 2026-07-13 = 100, so the nine categories rebuild the headline exactly. Documented end-to-end for the researchers, journalists, and analysts evaluating GroceryPulse as an alternative-data input.

One estimatorCGPI / v2
Base week100.00

2026-07-13

Every weekPt / P0

Matched prices

Same product. Same store. One common base.

01Collect
02Match
03Compute
04Audit
05Publish
Method schematic · not a price series
WeeklyUpdate cadence
50Basket items
9Categories
21Retailer banners
13Cities
Same-weekPublication
CGPI

Canadian Grocery Price Index

Published weekly to licensed subscribers across 13 cities and 21 banners. The methodology stays public.

How it works

Five automated stages run end-to-end every week, with no human in the loop between collection and publication.

  1. 01

    Collect

    Every Thursday at 08:00 UTC an automated pipeline reads publicly accessible retailer pages across 13 cities and 21 banners, extracting prices from server-rendered HTML. Any city below 90% store coverage is automatically re-scraped Friday.

  2. 02

    Match

    Each listing is matched to a canonical basket item by product type, then package size within ±10%, then variant. The cheapest valid match is kept.

  3. 03

    Compute

    Matched prices feed one weighted Jevons (geometric-mean) estimator, evaluated over every store leaf for the national figure, over a city's leaves for a city, and over a banner cell's leaves for that banner. The headline and the nine category sub-indices are the same direct fixed-base computation: each week is compared with the base week of 2026-07-13 over the items present in both, so nothing accumulates and the nine categories rebuild the headline exactly.

  4. 04

    Audit

    After every run a stratified sample is re-queried against the live sites; any mapping that fails two consecutive weeks is automatically retired from the index.

  5. 05

    Publish

    The index is recomputed and published the same week it is collected, giving a weekly read on advertised shelf prices.

Index formula

The headline (all-items) CGPI is a direct fixed-base, matched-model weighted Jevons price index (methodology v2, one estimator since 2026-08-12): a geometric mean of price relatives, the form recommended by the ILO/IMF Consumer Price Index Manual and used by Eurostat for elementary price aggregates. Every week is compared directly with the base week of 2026-07-13 (week ending Sunday 2026-07-19) = 100 over the items priced in both, so the level depends only on the base week and the week being published. Nothing accumulates, and re-running any week reproduces it. The headline is not chained: it was until 2026-08-12, and the revision log below records why that changed. The previous fixed-base series (v1, base week 2026-03-30) was frozen at the 2026-06-12 cutover and remains available via the API with series=v1.

The nine category sub-indices are the same estimator over a slice of the basket, on the same base week and the same store leaves. Each week is compared directly with the base week over the items present in both, and every price relative is formed within a single store and within one shelf slot, never across stores or banners. Within each product, the top and bottom 10 percent of store-level relatives are trimmed before averaging, which removes residual slot-occupant and price-basis switches that survive the quarantine. Nothing accumulates between weeks, so re-running any week reproduces it, and every level (national, city, or banner) reads as the change since the base week, which makes levels comparable with each other. Week-over-week, month-over-month and year-over-year changes are the ratio of two published levels (null after a missing week), so the tables reconcile with their own columns. Because the headline is the same estimator over the whole basket, the nine categories rebuild it exactly as a matched-weight geometric mean, and every run asserts that identity and fails rather than publishing a table whose parts do not add up. Chaining each category over its 4 to 7 matched items had let sample churn accumulate into the published level; the direct comparison removes that failure at the cost that a fixed base ages, as documented in the revision log below.

Headline and categories (one direct fixed-base estimator)
It = 100 × exp( Σ w′i × meani ln(Pit / Pi,base) )
meani: log relatives averaged per basket product, each relative formed within a single store and pinned to the shelf slot the base week used; base = the week of 2026-07-13. The headline runs this over all 50 items, each category over its own slice.
base
The base week: the week of July 13, 2026 (ending July 19, 2026) = 100. Every series, headline and category, national, city and banner, is compared with this one week.
w′ᵢ
Weight of product i, renormalized over the items priced in both the base week and week t
Pᵢₜ / Pᵢ,base
Price relative: product i's price this week against its price in the base week, in the same store and shelf slot
Iₜ
Index level: the change since the base week (= 100). The headline and the nine category sub-indices are one estimator, at national, city and banner level, so every level is comparable with every other as change since that week. A level is not a price level: basket cost in dollars says which city or banner is more expensive.

Substitution-bias correction

The geometric mean implicitly accounts for consumers switching to cheaper alternatives when one product's price rises — the arithmetic mean of a Laspeyres index does not.

Symmetric price changes

A +50% increase and a −50% decrease offset each other exactly under Jevons. Under an arithmetic mean they do not, which biases the index upward.

Worked example

Compute a weekly Jevons link yourself

Change any price below and the index recomputes as you type. Four items from the real 50-item basket, at their real basket weights. Everything on this panel is arithmetic you can reproduce in a spreadsheet in about two minutes, which is the point.

Scenario
2% milk4 L jug

Basket weight 0.030 · share of this example 26.1%

Relative P2 / P1
1.0274
Change
+2.74%
ln(relative)
+0.02707
w · ln(relative)
+0.00706
Chicken breast, boneless skinlessper kg

Basket weight 0.040 · share of this example 34.8%

Relative P2 / P1
1.0000
Change
0.00%
ln(relative)
0.00000
w · ln(relative)
0.00000
White bread675 g loaf

Basket weight 0.020 · share of this example 17.4%

Relative P2 / P1
1.0172
Change
+1.72%
ln(relative)
+0.01705
w · ln(relative)
+0.00296
Bananasper kg

Basket weight 0.025 · share of this example 21.7%

Relative P2 / P1
1.0258
Change
+2.58%
ln(relative)
+0.02545
w · ln(relative)
+0.00553

The weekly link, with your numbers in it

link = exp( Σ wᵢ · ln(Pᵢ,2 / Pᵢ,1) )
= exp( 0.261 × ln(7.49 / 7.29) + 0.348 × ln(15.99 / 15.99) + 0.174 × ln(3.55 / 3.49) + 0.217 × ln(1.99 / 1.94) ) = exp( +0.015557 ) = 1.015679
Index level (week 1 = 100)
101.57
Week over week
+1.57%
Items matched
4/4

Why geometric, and not an arithmetic mean

Feed the identical prices and identical weights into a weighted arithmetic mean of the same relatives — the Laspeyres form — and it reads higher. It always does: the arithmetic mean of a set of positive numbers is never below their geometric mean, and the gap widens with dispersion. Try One item spikes and watch them separate.

Jevons (what we publish)
101.57
+1.57%

exp( Σ wᵢ · ln rᵢ )

Arithmetic / Laspeyres
101.57
+1.57%

Σ wᵢ · rᵢ

Overstatement
+0.01
index points

Every week, compounding into the level.

The gap is substitution bias: an arithmetic mean implicitly assumes shoppers buy the same quantities whatever happens to relative prices, so an item that spikes drags the whole index with it, while a geometric mean allows for the shopper who buys less of what just got expensive.

Symmetry check: apply this week's changes, then reverse them exactly

A price that rises 50% and then falls 50% is back where it started, and an index that claims otherwise is inventing inflation. Chaining your week-2 relatives and then their exact inverses:

Jevons, round trip100.00
Arithmetic, round trip100.01

Jevons returns to exactly 100 for any set of price movements. The arithmetic mean lands above 100 whenever prices moved at all — a permanent upward drift manufactured by the formula rather than by the market. That is the whole reason the ILO/IMF CPI Manual and Eurostat recommend the geometric form for elementary aggregates, and the reason the CGPI uses it.

View the term-by-term arithmetic
Term-by-term computation of the Jevons link for the four illustrative basket items.
ItemWeightw (renorm.)Week 1Week 2Relativeln(rel)w · ln(rel)
2% milk0.0300.26097.297.491.0274+0.02707+0.00706
Chicken breast, boneless skinless0.0400.347815.9915.991.00000.000000.00000
White bread0.0200.17393.493.551.0172+0.01705+0.00296
Bananas0.0250.21741.941.991.0258+0.02545+0.00553
Σ w · ln(rel)+0.01556
Index = 100 × exp( Σ )101.57

This is an illustration, not published data. The prices above are plausible placeholders you can overwrite; no figure on this panel is a GroceryPulse observation. The published headline index runs the same link over the full matched item set at every city × banner cell, chains the weekly links into a level, and publishes a cell only where at least 60% of its basket slice (and at least two items) is priced in both weeks being linked. Because each headline series is rebased to 100 in its own entry week, headline levels are not comparable across cities or banners. The nine the headline and its category sub-indices are computed direct against the July 2026 base week (= 100), so category levels are comparable with each other.

The basket

50 products across 9 categories, weighted to approximate a typical Canadian household's grocery spend.

Meat & Protein
19.8%
7 items
Dairy & Eggs
15.6%
6 items
Produce — Fruits
10.4%
5 items
Produce — Vegetables
10.4%
6 items
Pantry Staples
10.4%
7 items
Household Essentials
9.4%
5 items
Bread & Bakery
8.3%
5 items
Frozen
8.3%
4 items
Beverages
7.3%
5 items

Weights approximate Statistics Canada's Food purchased from stores sub-basket. The category shares above are normalized and total 100%. The per-item weights in the full product list below are the raw ones, and those total 96.0% rather than 100%. That is deliberate, not a rounding gap: the raw weights are relative importances, and the index normalizes them before computing, then normalizes again inside each weekly link over the items actually priced in both weeks. An item missing at one banner is never treated as zero; its weight is redistributed across the items that are present. Bars are scaled to the largest category for legibility.

Full product listall 50 items with weights
#ProductCategoryWeight
12% Milk, 4LDairy & Eggs3.0%
2Butter, Salted, 454gDairy & Eggs2.5%
3Large Eggs, 12-packDairy & Eggs3.0%
4Cheddar Cheese, Medium, 400gDairy & Eggs2.5%
5Greek Yogurt, Plain, 750gDairy & Eggs2.0%
6Cream Cheese, 250gDairy & Eggs2.0%
7Chicken Breast, Boneless Skinless, per kgMeat & Protein4.0%
8Ground Beef, Lean, per kgMeat & Protein3.5%
9Pork Loin Chops, per kgMeat & Protein2.5%
10Bacon, 375gMeat & Protein2.0%
11Salmon Fillet, Atlantic, per kgMeat & Protein3.0%
12Canned Tuna, Chunk Light, 170gMeat & Protein1.5%
13White Bread, 675gBread & Bakery2.0%
14Whole Wheat Bread, 675gBread & Bakery2.0%
15Bagels, ~6-packBread & Bakery1.3%
16English Muffins, 6-packBread & Bakery1.3%
17Hamburger Buns, 8-packBread & Bakery1.4%
18Bananas, per kgProduce — Fruits2.5%
19Apples, ~2kg BagProduce — Fruits2.0%
20Strawberries, 454gProduce — Fruits2.0%
21Oranges, per kgProduce — Fruits1.8%
22Blueberries, Fresh 454g (1lb)Produce — Fruits1.8%
23Potatoes, 10lb BagProduce — Vegetables2.0%
24Onions, 3lb BagProduce — Vegetables1.5%
25Carrots, 2lb BagProduce — Vegetables1.5%
26Broccoli, per Head or CrownProduce — Vegetables1.8%
27Tomatoes, per kgProduce — Vegetables1.8%
28Romaine Lettuce, per HeadProduce — Vegetables1.5%
29White Rice (Long Grain), 2kgPantry Staples2.0%
30Pasta, Spaghetti, 900gPantry Staples1.7%
31Canned Tomatoes, Diced, 796mLPantry Staples1.3%
32Peanut Butter, 1kgPantry Staples1.5%
33Canola Oil, 946mLPantry Staples1.5%
34Granulated Sugar, 2kgPantry Staples1.0%
35All-Purpose Flour, 2.5kgPantry Staples1.0%
36Frozen Pizza, PepperoniFrozen2.0%
37Frozen Mixed Vegetables, 750gFrozen2.0%
38Ice Cream, 1LFrozen2.0%
39Frozen Chicken Nuggets, 700gFrozen2.0%
40Orange Juice, 2.63LBeverages1.8%
41Ground Coffee, 300gBeverages1.8%
42Tea Bags, ~72-packBeverages1.0%
43Coca-Cola, 2LBeverages1.3%
44Bottled Water, 24-pack 500mLBeverages1.3%
45Paper Towels, ~6-rollHousehold Essentials2.0%
46Toilet Paper, 12-rollHousehold Essentials2.0%
47Dish Soap, 535mLHousehold Essentials1.5%
48Laundry Detergent, 1.47LHousehold Essentials2.5%
49Garbage Bags, 40-countHousehold Essentials1.0%
50Chicken Thighs, Bone-In, per kgMeat & Protein2.5%

Coverage & collection

21 active banners across the three largest Canadian grocery parents plus two regional players, spanning discount and full-service formats in every province. Super C (pipeline-supported, no active stores) and Farm Boy (not currently collected) are listed below for completeness without counting toward the 21.

Loblaw Companies

10 banners
  • Loblaws — Ontario full-service flagship
  • No Frills — national discount banner
  • Real Canadian Superstore — large-format (Western Canada and Ontario)
  • Atlantic Superstore — large-format (Atlantic provinces)
  • Dominion — Newfoundland full-service
  • Maxi — Quebec discount banner
  • Provigo — Quebec full-service
  • Fortinos — Ontario full-service
  • Wholesale Club — bulk / small-format
  • Your Independent Grocer — smaller-market full-service

Empire Company (Sobeys)

8 banners
  • Sobeys — national full-service
  • FreshCo — national discount banner
  • IGA — Quebec full-service
  • Safeway — Western Canada full-service
  • Foodland — smaller-market full-service
  • Thrifty Foods — BC full-service
  • Farm Boy — Ontario specialty (via Voilà delivery)
  • Voilà — Sobeys online grocery delivery

Metro Inc.

3 banners
  • Metro — Ontario / Quebec full-service
  • Food Basics — Ontario discount banner
  • Super C — Quebec discount banner (pipeline-supported; no active stores currently tracked)

Independents / regional

2 banners
  • Save-On-Foods — Jim Pattison Group, Western Canada
  • Giant Tiger — discount / general merchandise with grocery

Source

Prices come from publicly accessible retailer websites — the same product pages any consumer can view. Price data is extracted from the server-rendered HTML.

Product matching

  1. 1. Type — category must match (milk, butter, chicken breast…).
  2. 2. Size — package size within ±10% of the target.
  3. 3. Variant — specifics checked (salted butter, whole-wheat bread).

The cheapest valid match is used, reflecting shoppers' tendency to choose store brands and sale items.

Schedule

Collected every Thursday at 08:00 UTC (04:00 Eastern), with an automatic Friday catch-up for any city below 90% store coverage. A complete run covers all 13 cities and 21 banners; runtime is typically 10–30 minutes depending on retailer response times and rate-limit backoffs. The index is recomputed after each run.

Quality assurance

After every weekly scrape, an automated audit re-runs the matching pipeline for a stratified sample against the live retailer sites — effectively re-scraping those items on a different day — and retires any mapping it can no longer match, so broken matches don't persist in the index. These re-scrape checks confirm reproducibility and mapping liveness, but they re-run the same pipeline — they are not independent evidence of accuracy. A second tier of independent, browser-based spot audits reads prices off the retailer page the way a shopper would; that sample is still small (70 audits to date), so we do not publish a headline accuracy percentage. Results from the stratified monthly audit program (target N ≥ 100) will be published here as they accumulate.

Re-run, don't re-read

The audit re-runs the same search-and-match pipeline the scrape uses, then checks whether a fresh run still finds a valid match for each sampled item — it reproduces the scrape rather than re-reading a single stored SKU.

Drift vs. defect

A re-run that finds the item at a different price is recorded as ordinary week-to-week price movement, not an error. Only a failure to find any spec-valid match flags a genuinely broken mapping.

Auto-retirement

A mapping is retired from the index only after a fresh scrape finds no valid match for it two weeks running — long enough to ride out a transient outage, quick enough to catch real breakage.

Known coverage gap

Voilà (and Farm Boy via Voilà delivery) cannot yet be re-checked by the automated audit — its consumer search interface requires an active postal-code session the pipeline cannot replay. Voilà observations are still collected in the normal scrape; they just don't receive the live re-check the other families do. Extending the audit loop to the full 21-banner panel is on the roadmap.

A formal validation study will be published once enough production history has accumulated. We make no claim of predictive power over any other price series in the meantime. Method notes are documented in the CGPI whitepaper.

What the CGPI measures

The CGPI measures advertised prices: the posted shelf price a shopper sees online, for a fixed basket, every week. Official consumer price statistics measure transaction prices, drawn largely from retailer scanner data, across a much broader basket, monthly. These are different measurements of different things. Neither substitutes for the other, and they should not be expected to move identically. The table below sets out where they differ.

FeatureCGPIOfficial food CPI
What is measuredAdvertised price posted online (sale-aware and regular both captured)Transaction price paid at the till
Price sourcePublic retailer listings, collected first-partyLargely retailer scanner data, supplemented by field and web collection
Update frequencyWeekly (Thursdays)Monthly
FormulaOne estimator for the headline and the nine categories: direct fixed-base matched-model weighted Jevons (geometric mean, methodology v2), base week of 2026-07-13 = 100Modified Laspeyres (arithmetic mean)
Basket size50 representative itemsseveral hundred representative food products (list revised monthly; no fixed count published)
Geographic scope13 cities across all 10 provincesNational + provincial
Banner coverage21 retailer banners (incl. all three parents: Loblaw, Metro, Empire)Not disclosed at banner level
TransparencyFull basket & methodology publishedBasket weights published, individual prices not

Revision log

Price observations are append-only: once written, an observation is never updated or deleted. Corrections are made at read time or as superseding rows, never as edits to history. Index values are recomputed under the current versioned code, and every published value stays retrievable as it was first published through the point-in-time vintage archive.

21 August 2026: the week ending 9 August 2026 was restated; the promotional-price fix had published as a price fall

What happened. The collection fix described in the entry below reached the panel in the collection of 6 August 2026. At the Empire banners (Sobeys, Safeway, FreshCo, Foodland, IGA) and at Voilà, the recorded price went from the regular price to the promotional price in one step, because those parsers had never been able to see a promotion at all. The index read that step as a price movement and published the week ending 9 August 2026 at 98.74, a fall of 1.40% on the week. No shelf price moved to produce most of it.

Why. The index compares each week directly with a fixed base week, currently the week of 13 July 2026. From 6 August a promotional price at those chains was being divided by a regular-price base, so a change in what we could see was measured as a change in what shoppers pay. Every check the pipeline ran passed: store and item coverage were normal for the week, and the safeguard that asks whether a move is concentrated in a few stores reported the opposite, because a collection change moves an entire chain at once.

Effect. About 1.2 of those 1.4 points was the collection change rather than any price. The three weeks before it are unaffected. Chain-level category cells were hit far harder than the headline, because a category carries only 4 to 7 items at a single chain.

Not every chain was affected, and that matters. The Metro banners and Save-On-Foods began recording the sale label in the same collection, but their recorded price was already the promotional one, so nothing about their measurement changed. The two cases are separated by measurable evidence: among items matched to the same store, product and product name, the share whose price fell more than 5% jumped from 0.9% to 18.4% at Empire and from 0.0% to 20.0% at Voilà, while Metro went 17.6% to 8.2% and Save-On 14.3% to 14.9%.

Remedy: the two chains step out, the index carries on. We will not substitute one price for another, or invent a promotional price for a week that never recorded one. Empire and Voilà are therefore excluded from the index for every week of the current series, not just the weeks after the change, so the panel stays constant and week-over-week remains a real price move. The base week of 13 July, the scale and the other chains are unchanged. Restated on that panel the series reads 100.00, 100.69, 100.39 and 99.60 for the week ending 9 August, a fall of 0.79%. Empire and Voilà return at the next re-base, once the base itself is past the change; returning them sooner would move the index 1.35 points with no shelf price behind it.

What this costs. Coverage. Thirty-three of 146 store panels leave the index while they are excluded, and the per-chain series for Sobeys, Safeway, FreshCo, Foodland, IGA, Thrifty Foods and Voilà are not published for this base period, because a chain measured against its own July prices is exactly the comparison that is broken. Promotional prices remain in the index for every chain that records them.

How this is prevented from recurring. A collection change is now declared in the codebase by whoever makes it, recording the chain, the week, the change and whether the price itself moved. The index independently derives each chain's recording behaviour week by week and refuses to publish any change no declaration covers, rather than guessing. Pre-revision values remain retrievable exactly as published through the point-in-time vintage archive (?asof= on /api/v1/index).

12 August 2026: the headline and the nine category sub-indices became one estimator, and the base moved to the week of 13 July 2026

What happened. Until this date the headline was a weekly chain while the nine categories were direct against a fixed base, and the two estimators shared no state. The parts therefore could not rebuild the whole: measured from 7 June to 2 August 2026, the chained headline read −2.00% while the matched-weight geometric mean of its own nine categories read −5.24%, and the gap widened every week. A reader who added up the table under the headline could not reach the headline, and was right to conclude that one of them was wrong.

Remedy. The headline now uses the same direct fixed-base, matched-model weighted Jevons estimator the categories use, over the same store leaves and against the same base week. The headline is that estimator run over all 50 basket items; each category is the same estimator run over its own slice. Every run rebuilds the national headline from the nine published national category levels and refuses to publish if the two disagree by more than 0.02 index points.

The base moved to the week of 13 July 2026 (week ending Sunday 19 July) = 100, replacing the week of 1 June 2026. The June base could not be audited: no observation before July carries a stored product name, and 33.4% of its store-product cells held more than one distinct price inside that single week, so the base level was whichever scrape landed last. Against that base the June mapping cleanup registered as a permanent price fall, with meat reading −20% where a same-store reference reads −5.7%.

What this costs. A cell with no store in the base week now publishes nothing at all, where the chain would have started it at 100 in its first week, so a banner or city onboarded after 13 July 2026 waits for the next re-base. Week-over-week, month-over-month and year-over-year are now the ratio of two published levels rather than separate chain links, which is a deliberate trade: every published percentage can be recomputed from two published numbers.

12 August 2026: the headline and the nine category sub-indices became one estimator

What happened. Until this date the headline was a weekly chain over city and banner cells while the categories were direct against a fixed base, and the two shared no state. The parts could not rebuild the whole: measured 2026-06-07 to 2026-08-02, the chained headline read −2.00% while the matched-weight geometric mean of its own nine categories read −5.24%, and the gap grew every week. A reader who weighted the table under the headline could not get the headline, and was right to conclude one of them was wrong.

Remedy. The headline is now the same direct fixed-base matched-model Jevons estimator as the categories, run over the whole 50-item basket instead of one slice of it, over the same store leaves and against the same base week of 13 July 2026. Nothing is chained. Weighting the nine published category levels by their matched weights and taking the geometric mean now rebuilds the published headline exactly, and the publishing run asserts that identity every week and refuses to publish if it fails.

What this changes for a reader. Every level, at national, city and banner level, now reads as the change since the base week rather than since the week that series entered the panel, so levels can be read against each other on that basis. Basket cost in dollars remains the measure of how expensive a city or banner is. Week-over-week and month-over-month changes are ratios of two published levels, so every published percentage can be recomputed from two published numbers. Values published under the chain remain retrievable exactly as published through the point-in-time vintage archive (?asof= on /api/v1/index).

10 August 2026: the nine category sub-indices were restated on a direct fixed-base method

What happened. An institutional reader flagged on 8 August 2026 that the published category sub-indices did not reconcile with the headline index. Weighted together, the nine category series read roughly +0.5% since the week of 2026-06-01 while the headline read roughly −2.0% over the same window, and category paths contained moves no shelf price made: household down 15.8% in a single week, frozen up 36% in two months. Those were changes in the matched sample, not changes in prices.

Why. Each category sub-index was chained weekly over only 4 to 7 matched items, and that matched set churns week to week as items drop out and return, with sale-price bouncing amplifying the effect. Every substitution left a small permanent error in the accumulated level. The headline carries 44 to 47 of the roughly 50 basket items each week, so the same churn averages out; it was checked against a direct matched-pair computation and stands.

Effect. Published category levels and percentage changes were wrong by up to roughly five percentage points in either direction. The headline (all-items) index was unaffected.

Remedy. Every published category week was restated on 10 August 2026 as a direct fixed-base matched-model Jevons index: each week is compared directly with the base week of 2026-06-01 (= 100), every price relative is formed within a single store, and nothing accumulates between weeks, so re-running any week reproduces it. The headline methodology is unchanged, and the headline rows were machine-verified byte-identical before and after the revision. Pre-revision category values remain retrievable exactly as published through the point-in-time vintage archive (?asof= on /api/v1/index).

Still limited. A direct fixed-base comparison ages: coverage of the base week decays as the store panel changes. A category week publishes only when at least 60% of its slice matches the base week, a warning fires when national coverage falls below 75%, and if coverage erodes the series will be re-based with disclosure rather than patched. A store or banner onboarded after the base week contributes no price relatives, and a banner cell with no base-week data publishes no category series.

3 August 2026 — promotional prices were not captured at the Empire banners, Voilà and Farm Boy

What happened. Our collection recorded the regular price at Sobeys, Safeway, FreshCo, Foodland, IGA, Thrifty Foods, Voilà and Farm Boy, and missed the promotional prices those chains were running. At the Metro banners and Save-On the recorded price was correct; only the sale label was missing.

Why. Two separate collection defects. The Empire banners publish the promotional price in a field our scraper never requested, and an earlier fix targeted a field that is never populated, so it had never taken effect. For Voilà the promotional price arrived in every response and was discarded before it reached the parser.

Effect. Prices at the affected chains read high in any week where an item was on promotion, measured at roughly 2.8% to 3.0% against the retailers' own published payloads. Because those chains sit at the expensive end of most cross-chain comparisons, spreads published for affected weeks are overstated. The direction of those findings is unchanged: discount chains are cheaper by a large double-digit margin.

Remedy. Corrected in collection on 3 August 2026. History has not been rewritten. Corrected figures are published alongside the originals rather than replacing them, and pre-revision index values remain available through the vintage archive.

Still limited. Save-On-Foods publishes its reduced price with no pre-promotion reference, so its promotions have a knowable window and an unknowable depth. Promotional depth remains available for the Loblaw banners, Giant Tiger, the Empire banners and Voilà only.

Limitations

Disclosed openly in the spirit of transparency. The index is designed to complement, not replace, official statistics.

Online prices only

In-store prices may differ, especially for produce and meat.

13 cities

Coverage spans major cities across Canada, but rural areas are not tracked.

No Costco or Walmart

Bot protection prevents reliable automated price collection from these retailers.

50-item basket

The official food basket tracks several hundred representative products (the list is revised monthly). A tighter basket may not capture every price movement, especially in less-frequently-purchased categories.

No quality adjustment

If a product is reformulated we track the price change but not the quality change. Shrinkflation (pack-size reduction) is tracked explicitly; other reformulations are not.

Commercial access

The full per-observation panel, weekly CSV pack, and point-in-time Parquet dumps are available via commercial license, with a 14-day evaluation trial.

We use cookies for analytics to improve your experience. Privacy Policy