Methodology · Canadian Grocery Price Index
How the CGPI is built
A weekly, chained weighted-Jevons grocery price index (methodology v2), computed from a fixed 50-item basket priced across 22 retailer banners and 13 Canadian cities. Documented end-to-end for the researchers, journalists, and analysts evaluating GroceryPulse as an alternative-data input.
How it works
Five automated stages run end-to-end every week, with no human in the loop between collection and publication.
- 01
Collect
Every Thursday at 08:00 UTC an automated pipeline reads publicly accessible retailer pages across 13 cities and 22 banners, extracting prices from server-rendered HTML. Any city below 90% store coverage is automatically re-scraped Friday.
- 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.
- 03
Compute
Matched prices feed a chained weighted Jevons (geometric-mean) index: each week links to the previous week over the items priced in both, computed per city and banner and rolled up to a national figure.
- 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.
- 05
Publish
The index is recomputed and published the same week — weeks ahead of Statistics Canada's monthly CPI and its three-week reporting lag.
Index formula
The CGPI is a chained, matched-model weighted Jevons price index (methodology v2, adopted 2026-06-12) — a geometric mean of week-over-week price relatives, the form recommended by the ILO/IMF Consumer Price Index Manual and used by Eurostat for elementary price aggregates. Each week is compared with the previous week over the items priced in both weeks, so week-over-week changes are same-composition by construction; the index level is the accumulated product of those weekly links. 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.
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.
The basket
50 products across 9 categories, weighted to approximate a typical Canadian household's grocery spend.
Weights approximate Statistics Canada's Food purchased from stores sub-basket and are renormalized to 100% inside the index. Bars are scaled to the largest category for legibility.
Full product listall 50 items with weights
| # | Product | Category | Weight |
|---|---|---|---|
| 1 | 2% Milk, 4L | Dairy & Eggs | 3.0% |
| 2 | Butter, Salted, 454g | Dairy & Eggs | 2.5% |
| 3 | Large Eggs, 12-pack | Dairy & Eggs | 3.0% |
| 4 | Cheddar Cheese, Medium, 400g | Dairy & Eggs | 2.5% |
| 5 | Greek Yogurt, Plain, 750g | Dairy & Eggs | 2.0% |
| 6 | Cream Cheese, 250g | Dairy & Eggs | 2.0% |
| 7 | Chicken Breast, Boneless Skinless, per kg | Meat & Protein | 4.0% |
| 8 | Ground Beef, Lean, per kg | Meat & Protein | 3.5% |
| 9 | Pork Loin Chops, per kg | Meat & Protein | 2.5% |
| 10 | Bacon, 375g | Meat & Protein | 2.0% |
| 11 | Salmon Fillet, Atlantic, per kg | Meat & Protein | 3.0% |
| 12 | Canned Tuna, Chunk Light, 170g | Meat & Protein | 1.5% |
| 13 | White Bread, 675g | Bread & Bakery | 2.0% |
| 14 | Whole Wheat Bread, 675g | Bread & Bakery | 2.0% |
| 15 | Bagels, ~6-pack | Bread & Bakery | 1.3% |
| 16 | English Muffins, 6-pack | Bread & Bakery | 1.3% |
| 17 | Hamburger Buns, 8-pack | Bread & Bakery | 1.4% |
| 18 | Bananas, per kg | Produce — Fruits | 2.5% |
| 19 | Apples, ~2kg Bag | Produce — Fruits | 2.0% |
| 20 | Strawberries, 454g | Produce — Fruits | 2.0% |
| 21 | Oranges, per kg | Produce — Fruits | 1.8% |
| 22 | Blueberries, Fresh 454g (1lb) | Produce — Fruits | 1.8% |
| 23 | Potatoes, 10lb Bag | Produce — Vegetables | 2.0% |
| 24 | Onions, 3lb Bag | Produce — Vegetables | 1.5% |
| 25 | Carrots, 2lb Bag | Produce — Vegetables | 1.5% |
| 26 | Broccoli, per Head or Crown | Produce — Vegetables | 1.8% |
| 27 | Tomatoes, per kg | Produce — Vegetables | 1.8% |
| 28 | Romaine Lettuce, per Head | Produce — Vegetables | 1.5% |
| 29 | White Rice (Long Grain), 2kg | Pantry Staples | 2.0% |
| 30 | Pasta, Spaghetti, 900g | Pantry Staples | 1.7% |
| 31 | Canned Tomatoes, Diced, 796mL | Pantry Staples | 1.3% |
| 32 | Peanut Butter, 1kg | Pantry Staples | 1.5% |
| 33 | Canola Oil, 946mL | Pantry Staples | 1.5% |
| 34 | Granulated Sugar, 2kg | Pantry Staples | 1.0% |
| 35 | All-Purpose Flour, 2.5kg | Pantry Staples | 1.0% |
| 36 | Frozen Pizza, Pepperoni | Frozen | 2.0% |
| 37 | Frozen Mixed Vegetables, 750g | Frozen | 2.0% |
| 38 | Ice Cream, 1L | Frozen | 2.0% |
| 39 | Frozen Chicken Nuggets, 700g | Frozen | 2.0% |
| 40 | Orange Juice, 2.63L | Beverages | 1.8% |
| 41 | Ground Coffee, 300g | Beverages | 1.8% |
| 42 | Tea Bags, ~72-pack | Beverages | 1.0% |
| 43 | Coca-Cola, 2L | Beverages | 1.3% |
| 44 | Bottled Water, 24-pack 500mL | Beverages | 1.3% |
| 45 | Paper Towels, ~6-roll | Household Essentials | 2.0% |
| 46 | Toilet Paper, 12-roll | Household Essentials | 2.0% |
| 47 | Dish Soap, 535mL | Household Essentials | 1.5% |
| 48 | Laundry Detergent, 1.47L | Household Essentials | 2.5% |
| 49 | Garbage Bags, 40-count | Household Essentials | 1.0% |
| 50 | Chicken Thighs, Bone-In, per kg | Meat & Protein | 2.5% |
Coverage & collection
22 active banners across the three largest Canadian grocery parents plus two regional players — spanning discount and full-service formats in every province. Super C is pipeline-supported but currently has no active stores, so it is listed below for completeness without counting toward the 22.
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. Type — category must match (milk, butter, chicken breast…).
- 2. Size — package size within ±10% of the target.
- 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 22 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 22-banner panel is on the roadmap.
A formal backtest against the Statistics Canada food-CPI benchmark will be published once enough monthly overlap has accumulated (targeted Q3 2026). Preliminary overlap observations are documented in the CGPI whitepaper.
CGPI vs StatCan CPI
The index is designed to complement official statistics — higher frequency and fully transparent, not a replacement for the authoritative benchmark.
| Feature | CGPI | StatCan CPI (Food) |
|---|---|---|
| Update frequency | Weekly (Thursdays) | Monthly (3-week lag) |
| Formula | Chained weighted Jevons (geometric mean, methodology v2) | Modified Laspeyres (arithmetic mean) |
| Basket size | 50 representative items | several hundred representative food products (list revised monthly; no fixed count published) |
| Price source | Online listings (public) | In-store price collectors |
| Geographic scope | 13 cities across all 10 provinces | National + provincial |
| Banner coverage | 22 retailer banners (incl. all three parents: Loblaw, Metro, Empire) | Not disclosed at banner level |
| Transparency | Full basket & methodology published | Basket weights published, individual prices not |
| Substitution bias | Lower (geometric mean) | Higher (arithmetic mean) |
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
StatCan's 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.