Sample data. The change history below is placeholder content for development. It is not a verified record of what these vendors charge. See the methodology for how the real data is collected.
Skip to content
PriceShift

How change detection works

The full pipeline, the rules that prevent false alarms, and the cases where we deliberately report nothing.

Last reviewed

This page describes exactly how a change gets from a vendor's pricing page onto this site, and where the process deliberately fails. If you spot a case where we got it wrong, tell us.

The pipeline

  1. Fetch. Each vendor's public pricing page is requested with an identifying user agent that links here, on a published schedule (currently twice daily, with per-vendor intervals configurable). Responses are capped and streamed so a large page cannot exhaust memory.
  2. Extract. Three strategies are tried in order of trustworthiness: JSON-LD structured data, then schema.org microdata, then a heuristic pass over the rendered text. The first strategy to yield at least two plans wins.
  3. Normalise. Tier names are mapped onto a shared vocabulary, so a vendor's "Hobby" and another's "Starter" are recognised as the same tier and a rename is not reported as a removal plus an addition.
  4. Hash. A canonical representation of the extracted data is hashed. If the hash matches the previous snapshot, the crawl ends there — cosmetic markup changes never create a record.
  5. Diff. Plans are matched by tier and compared field by field: price, billing period, seat allowance, numeric limits, feature list.
  6. Publish. Differences are written with a timestamp, the severity, and a link to the source page. A first crawl writes a baseline and reports no changes, because a starting point is not news.

Decisions that prevent false alarms

Most of the engineering here exists to avoid reporting things that are not changes. These are the rules:

Annual prices are compared monthly

A plan moving from "$10 per month billed monthly" to "$100 per year billed annually" is not a 900% increase. Both are normalised to a monthly basis before comparison, so a genuinely cheaper annual quote is reported as a decrease.

Usage-based pricing is excluded

If a price varies with consumption it is not a price. Comparing usage-tier figures run to run would produce a stream of meaningless changes, so they are stored but never diffed.

Sub-dollar movements are ignored

Changes below $0.50 on a monthly basis are treated as rounding noise. Reporting "$10.00 becomes $10.30" costs reader trust and gains nothing.

A failed extraction is a failure, not a deletion

If a crawl returns fewer than two plans, it is recorded as a failed run and retried with backoff. It is never treated as "the vendor removed all their plans". This is the single most important safeguard in the system, because conflating the two would be indistinguishable from real news until someone checked the vendor's site.

Removals and renames are distinguished

When a plan disappears, the system first checks whether an identical plan reappeared under a different display name. If so it is recorded as a rename. A simultaneous add and remove on the same tier is collapsed into a single packaging change rather than two entries.

Severity, and what it means

SeverityAssigned to
CriticalTerms of service changes that alter rights, liability or data handling
MajorPrice increases, removed features, removed plans, withdrawn published pricing, limits cut by more than half
MinorPrice decreases, added features, added plans, limits raised, plan renames

What we do not track, and why

  • Negotiated and enterprise pricing. Not public, therefore not verifiable, therefore not tracked.
  • Usage-based figures. See above.
  • Vendor announcements. A press release is a claim, not an observation. We report what the pricing page says, and link to it.
  • Anything behind a login. Only publicly reachable pages are crawled.

Crawl ethics

We request public pages at a low rate, identify the bot honestly, and honour a standard exclusion mechanism. If you run a vendor we track and would prefer we not crawl you, adding /robots.txt disallow rules will be respected. Requests are spread across the day and retried with backoff rather than repeated aggressively.

Verifying a figure yourself. Every change entry links to the source URL. If a number on this site disagrees with the vendor's live page, send us the link and we will investigate and correct it.

Coverage to date

The site currently tracks 18 vendors and has recorded 21 changes. The archive is the asset: the longer it runs, the more of the pricing history becomes impossible for a new entrant to reconstruct.