Documentation
Reading the analytics evidence table
What one row of the analytics table compares, how confidence and priority are composed, and the judgements the table refuses to make.
Last reviewed against the product on .
The analytics surface at /app/analytics is the full evidence table behind every market movement this site reports. It is built to show the arithmetic rather than the conclusion, so a figure on it can be checked instead of believed.
What one row is
A row is a comparison between the two most recent observations in one comparison group. A group holds everything identical except the date: country, region, city, market name, provider, provider item name, data level, unit and currency. Nine dimensions have to agree before a percentage is calculated, and nothing is converted to make an agreement happen.
Two situations produce no row at all. A group holding only one observation has nothing to compare against. A group whose older value is zero or negative is rejected, because a percentage change measured against a zero baseline is not a number.
What each scope reads
The scope switch at the top of the page chooses between your organization's home country and every country the site holds. Both are capped.
- Home-country scope
- 2,000 rows
- the most recent observations for your country
- All-countries scope
- 10,000 rows
- the most recent observations across every country
- Purchase rows read
- 10,000
- your own imports, used only for weighting and impact
- Observations per row
- 2
- the newest in the group and the one before it
Measured from getMarketAnalytics in src/lib/analytics/queries.ts.
The caps are worth knowing before you read a country's history as complete. A provider with more history than the cap is compared on its recent end, and older observations in the same group are simply not in the query.
The four columns that carry judgement
Change is the only unambiguous one: current minus prior, divided by prior, times one hundred.
Impact is two different quantities sharing one column. Where your imported purchasing matches the observation, it is your matched spend multiplied by the change. Where nothing matched, it is the signed movement of the observation itself, in whatever unit that observation uses. The cell prints a bare number either way, so the column is only meaningful once you know whether a match existed. Market data against your own costs sets out how that match is made and how often it fails.
Confidence is a 0 to 100 evidence score, not a probability. Nothing on this page estimates the chance that a price will move again.
| Component | Weight | What it measures |
|---|---|---|
| Coverage | 35% | Observations in the group against the number that cadence should have produced |
| Freshness | 25% | How far past its expected cadence the newest observation is |
| Source quality | 25% | The lower of the two observations' stored provider confidence |
| Match quality | 15% | Fixed at full marks on this page, because a group is exact by construction |
Measured from confidenceScore in src/lib/analytics/engine.ts, called from src/lib/analytics/queries.ts.
That last row is a limit rather than a detail. Because a comparison group already requires nine exact matches, match quality contributes the same amount to every row on the page and never separates one from another.
Priority is the sort order, and it is the one figure on the page that is partly about you: 55% movement severity, 30% spend weight, 15% confidence. Severity reaches its maximum at an absolute change of 25%, so every larger movement scores the same on that component. Spend weight is your matched spend for that item relative to your largest matched spend, which means priority reorders the table around what you actually buy.
Freshness is judged against the source, not the calendar
A monthly series is not stale for being weeks old. The page knows each provider's cadence and holds it to that, which is why a producer price series published once a year does not sink to the bottom of the table for most of the year.
| Cadence | Expected within | Observations for full coverage |
|---|---|---|
| Daily | 3 days | 30 |
| Weekly | 10 days | 8 |
| Fortnightly | 20 days | 6 |
| Dekadal | 15 days | 9 |
| Monthly | 45 days | 6 |
| Annual | 450 days | 2 |
| Anything else | 30 days | 4 |
Measured from expectedFreshnessDays and expectedHistoryPoints in src/lib/analytics/queries.ts.
Past the expected window, freshness falls away gradually rather than switching off, so an overdue series loses score without disappearing.
What this page will not tell you
It also cannot tell you that a movement will continue. Two observations describe a step, not a trend, and the page draws no line through them. A long series still contributes exactly two observations to the row you are reading, and the rest of it counts only towards coverage.
Where to look next
Your own invoice movements are a separate calculation on a separate page: see how price changes are detected. The published methodology and the coverage page cover how observations reach the database in the first place.