The dataset

Every field, every null, and the boundary of what is watched — so the data is checkable, not just readable.

Download

One row per (competitor, tier, price state). Regenerated and committed on every export, so any past state is retrievable from git history.

Schema

Field names, types, and null semantics — the same on both files.

Dataset field names, types, and null semantics
FieldTypeNotes
competitorstringThe company name.
tierstringThe pricing tier name as it appears on the source page.
first_observed_atISO 8601 timestampWhen this tier state was first observed.
last_observed_atISO 8601 timestampThe last observation still holding this same state — one row covers the whole run, not one row per check.
monthly_price_usdnumber | nullEmpty / null means contact sales, never free. A free tier is $0, written explicitly.
annual_price_usdnumber | nullSame null semantics as monthly_price_usd.
billing_unit"per_seat" | "flat" | "usage" | "unknown""unknown" means the source page did not state it, not that none applies.
included_seatsnumber | nullNull when the tier has no seat limit or the page does not state one.
is_freebooleanTrue only for an explicit $0 tier.
is_enterprisebooleanThe source page's own enterprise/custom-pricing tier, not an inference from price.
currencystringAlways "USD" — non-USD extractions are recorded internally but excluded from the published dataset.
provenance"live" | "wayback" | "mixed"See the legend below.

Provenance legend

live
Every observation in this row's run was a direct fetch of the source page.
wayback
Every observation in this run was reconstructed from an Internet Archive capture.
mixed
The run spans both — a live fetch confirmed a state first seen in a Wayback capture, or vice versa.

Methodology

  • Every watched source is checked once daily at 07:00 CT (±30m jitter), plus a weekly synthesis run.
  • Pricing is extracted from the raw page HTML by a schema-constrained LLM call. Every numeric price in the output must be findable as a numeral in the page text it was given — a price the model produced but the page never contained fails this grounding check and is never written.
  • A candidate change is not published until its new value is observed a second time: live changes confirm the next day, backfilled changes confirm against the following capture. This is the single confirmation rule for both paths.
  • Curation policy: a change observed only once, with no persisting second observation, is re-checked by re-extracting both snapshots. Agreement confirms it; disagreement retracts it — and the exclusion is recorded, not silently dropped.
  • Resolution differs by source: backfilled history comes from monthly Internet Archive captures, so a change is dated to within a month of when it actually happened, and two changes inside one month can appear as one. Live observations are daily. The provenance column tells you which applies to any given row.

Boundary

Six developer-infrastructure companies were verified by hand as server-rendering their prices in raw HTML: Linear, Notion, Figma, Supabase, Sentry, Postman.

Screened 51 companies; 21 publish comparable plan pricing.

A further 51 developer-infrastructure companies were screened programmatically (bellwether qualify): each candidate's pricing page was fetched, scored for a plausible price-and-tier signal, then run through two independent live extractions. 21 admitted — both extractions agreeing on a plausible tier count (41.2% of the pool) — bringing the watch list to 27 sources. Naming the exclusions is what makes the inclusions credible.

Admitted, by category

auth (2)
Auth0, Clerk
ci-and-build (4)
Buildkite, Depot, GitHub, GitLab
data-tooling (1)
Hasura
databases (4)
PlanetScale, Redis Cloud, Turso, Upstash
email (2)
Postmark, Resend
feature-flags (1)
Statsig
hosting (4)
Fly.io, Netlify, Render, Vercel
observability (2)
Honeycomb, New Relic
vector-stores (1)
Pinecone

Vercel now qualifies. This project's own spec named Vercel the canonical qualification failure: a client-rendered shell with no price in the raw HTML. The screen tests that claim rather than assuming it, and on it no longer held — Vercel's page is server-rendered and extracts as Hobby $0 / Pro $20 / Enterprise contact. That is why it is in the watch list, not an exception to the boundary.

Datadog, Cloudflare, and Fastly publish server-rendered pricing — the screen found real prices in their raw HTML, same as every admitted source. Each is excluded because it prices per product or per unit of usage rather than per plan, so neither extraction attempt reproduced a plan table comparable to the rest of the watch list. They are excluded for comparability, not because they publish nothing.

Excluded (30)

27 reached extraction but did not qualify: extraction failed grounding or schema (16); attempts did not reproduce a plausible tier count (11). 3 more never reached extraction — the pre-filter found essentially no price signal on the page at all.

Every screened-out company, its category, and why it was excluded
CompanyCategoryWhy excluded
Algoliasearch
Attempts did not reproduce a plausible tier count

attempt 1 extracted 1 priced tier, attempt 2 extracted 1 priced tier

Better Stackobservability
Attempts did not reproduce a plausible tier count

attempt 1 extracted 3 priced tiers, attempt 2 extracted 12 priced tiers

Bunnyedge-and-cdn
Attempts did not reproduce a plausible tier count

attempt 1 extracted 0 priced tiers, attempt 2 extracted 0 priced tiers

CircleCIci-and-build
Extraction failed grounding or schema

attempt 1 failed: ungrounded: usage_rates.IP ranges per GB of data used.unit_price_usd = 0.27 does not appear in the page text, attempt 2 failed: ungrounded: usage_rates.credits per minute (Linux Medium).unit_price_usd = 0.06 does not appear in the page text; usage_rates.credits per GB (IP ranges).unit_price_usd = 0.27 does not appear in the page text

Cloudflareedge-and-cdn
Extraction failed grounding or schema

attempt 1 failed: ungrounded: usage_rates.vCPU-second.unit_price_usd = 0.00002 does not appear in the page text; usage_rates.GB-second.unit_price_usd = 7e-8 does not appear in the page text, attempt 2 failed: ungrounded: usage_rates.CPU.unit_price_usd = 0.00002 does not appear in the page text; usage_rates.Disk.unit_price_usd = 7e-8 does not appear in the page text

Convexdatabases
Extraction failed grounding or schema

attempt 1 failed: ungrounded: tiers.Free.monthly_price_usd = 0 does not appear in the page text, attempt 2 failed: ungrounded: tiers.Free.monthly_price_usd = 0 does not appear in the page text

Datadogobservability
Attempts did not reproduce a plausible tier count

attempt 1 extracted 27 priced tiers, attempt 2 extracted 26 priced tiers

Dopplersecrets
Extraction failed grounding or schema

attempt 1 failed: ungrounded: tiers.Developer.monthly_price_usd = 0 does not appear in the page text, attempt 2 failed: ungrounded: tiers.Developer.monthly_price_usd = 0 does not appear in the page text

Fastlyedge-and-cdn
Extraction failed grounding or schema

attempt 1 failed: ungrounded: usage_rates.Image Requests (10 Million - 50 Million, per 10,000).unit_price_usd = 0.15 does not appear in the page text; usage_rates.Image Requests (50 Million - 150 Million, per 10,000).unit_price_usd = 0.07 does not appear in the page text; usage_rates.AI Accelerator (20,000 - 2 Million, per 1,000 requests).unit_price_usd = 0.4 does not appear in the page text; usage_rates.Compute Requests (500 Million - 5 Billion, per 1 Million).unit_price_usd = 0.49 does not appear in the page text; usage_rates.Compute Requests (5 Billion - 20 Billion, per 1 Million).unit_price_usd = 0.48 does not appear in the page text; usage_rates.Compute Requests (50 Billion - 125 Billion, per 1 Million).unit_price_usd = 0.4 does not appear in the page text; usage_rates.Compute vCPU Milliseconds (5 Billion - 50 Billion, per 1 Million).unit_price_usd = 0.0495 does not appear in the page text; usage_rates.Compute vCPU Milliseconds (50 Billion - 200 Billion, per 1 Million).unit_price_usd = 0.048 does not appear in the page text; usage_rates.Compute vCPU Milliseconds (200 Billion - 500 Billion, per 1 Million).unit_price_usd = 0.045 does not appear in the page text; usage_rates.Compute vCPU Milliseconds (500 Billion - 1 Trillion, per 1 Million).unit_price_usd = 0.04 does not appear in the page text; usage_rates.Fanout Messages (500 Million - 3 Billion, per 1 Million).unit_price_usd = 0.8 does not appear in the page text; usage_rates.DDoS Protection (500 Million - 3 Billion, per 10,000 requests).unit_price_usd = 0.1 does not appear in the page text; usage_rates.DDoS Protection (3 Billion - 15 Billion, per 10,000 requests).unit_price_usd = 0.04 does not appear in the page text; usage_rates.Key Value Store Class A Operations (100,000 - 1 Million, per 100,000).unit_price_usd = 0.65 does not appear in the page text, attempt 2 failed: ungrounded: usage_rates.Image Requests per 10,000 (10 Million - 50 Million).unit_price_usd = 0.15 does not appear in the page text; usage_rates.Image Requests per 10,000 (50 Million - 150 Million).unit_price_usd = 0.07 does not appear in the page text; usage_rates.AI Accelerator per 1,000 Requests (20,000 - 2 Million).unit_price_usd = 0.4 does not appear in the page text; usage_rates.Compute Requests per 1 Million (500 Million - 5 Billion).unit_price_usd = 0.49 does not appear in the page text; usage_rates.Compute Requests per 1 Million (5 Billion - 20 Billion).unit_price_usd = 0.48 does not appear in the page text; usage_rates.Compute Requests per 1 Million (50 Billion - 125 Billion).unit_price_usd = 0.4 does not appear in the page text; usage_rates.Compute vCPU Milliseconds per 1 Million (5 Billion - 50 Billion).unit_price_usd = 0.0495 does not appear in the page text; usage_rates.Compute vCPU Milliseconds per 1 Million (50 Billion - 200 Billion).unit_price_usd = 0.048 does not appear in the page text; usage_rates.Compute vCPU Milliseconds per 1 Million (200 Billion - 500 Billion).unit_price_usd = 0.045 does not appear in the page text; usage_rates.Compute vCPU Milliseconds per 1 Million (500 Billion - 1 Trillion).unit_price_usd = 0.04 does not appear in the page text; usage_rates.Fanout Messages per 1 Million (500 Million - 3 Billion).unit_price_usd = 0.8 does not appear in the page text; usage_rates.DDoS Protection Requests per 10,000 (500 Million - 3 Billion).unit_price_usd = 0.1 does not appear in the page text; usage_rates.DDoS Protection Requests per 10,000 (3 Billion - 15 Billion).unit_price_usd = 0.04 does not appear in the page text; usage_rates.Key Value Store Class A Operations per 100,000 (100,000 - 1 Million).unit_price_usd = 0.65 does not appear in the page text

Grafana Cloudobservability
Extraction failed grounding or schema

attempt 1 failed: ungrounded: usage_rates.per GB Process (Logs).unit_price_usd = 0.05 does not appear in the page text; usage_rates.per GB Write (Logs).unit_price_usd = 0.4 does not appear in the page text; usage_rates.per GB Retain (Logs).unit_price_usd = 0.1 does not appear in the page text; usage_rates.per GB Process (Traces).unit_price_usd = 0.05 does not appear in the page text; usage_rates.per GB Write (Traces).unit_price_usd = 0.4 does not appear in the page text; usage_rates.per GB Retain (Traces).unit_price_usd = 0.1 does not appear in the page text; usage_rates.per GB Process (Profiles).unit_price_usd = 0.05 does not appear in the page text; usage_rates.per GB Write (Profiles).unit_price_usd = 0.4 does not appear in the page text; usage_rates.per GB Retain (Profiles).unit_price_usd = 0.1 does not appear in the page text; usage_rates.per host hour (Kubernetes Monitoring).unit_price_usd = 0.01 does not appear in the page text; usage_rates.per 1k sessions (Frontend Observability).unit_price_usd = 0.75 does not appear in the page text; usage_rates.per host hour (Database Observability).unit_price_usd = 0.07 does not appear in the page text; usage_rates.per virtual user hour (Performance Testing k6).unit_price_usd = 0.15 does not appear in the page text, attempt 2 failed: ungrounded: usage_rates.GB Process (Logs).unit_price_usd = 0.05 does not appear in the page text; usage_rates.GB Write (Logs).unit_price_usd = 0.4 does not appear in the page text; usage_rates.GB Retain (Logs).unit_price_usd = 0.1 does not appear in the page text; usage_rates.GB Process (Traces).unit_price_usd = 0.05 does not appear in the page text; usage_rates.GB Write (Traces).unit_price_usd = 0.4 does not appear in the page text; usage_rates.GB Retain (Traces).unit_price_usd = 0.1 does not appear in the page text; usage_rates.GB Process (Profiles).unit_price_usd = 0.05 does not appear in the page text; usage_rates.GB Write (Profiles).unit_price_usd = 0.4 does not appear in the page text; usage_rates.GB Retain (Profiles).unit_price_usd = 0.1 does not appear in the page text; usage_rates.per host hour (Kubernetes Monitoring).unit_price_usd = 0.01 does not appear in the page text; usage_rates.1k sessions (Frontend Observability).unit_price_usd = 0.75 does not appear in the page text; usage_rates.per host hour (Database Observability).unit_price_usd = 0.07 does not appear in the page text; usage_rates.virtual user hour (Performance Testing k6).unit_price_usd = 0.15 does not appear in the page text

Herokuhosting
Extraction failed grounding or schema

attempt 1 failed: invalid: Failed to parse structured output: Error: Failed to parse structured output as JSON: Expected ',' or '}' after property value in JSON at position 14730 (line 1 column 14731), attempt 2 failed: invalid: Failed to parse structured output: Error: Failed to parse structured output as JSON: Expected ',' or '}' after property value in JSON at position 14608 (line 1 column 14609)

Infisicalsecrets
Extraction failed grounding or schema

attempt 1 failed: ungrounded: tiers.Pro.annual_price_usd = 264 does not appear in the page text; tiers.Advanced.annual_price_usd = 528 does not appear in the page text, attempt 2 failed: ungrounded: tiers.Pro.annual_price_usd = 240 does not appear in the page text; tiers.Advanced.annual_price_usd = 480 does not appear in the page text

LaunchDarklyfeature-flags
Attempts did not reproduce a plausible tier count

attempt 1 extracted 1 priced tier, attempt 2 extracted 1 priced tier

Lemon Squeezypayments
Extraction failed grounding or schema

attempt 1 failed: ungrounded: usage_rates.per transaction.unit_price_usd = 0.05 does not appear in the page text, attempt 2 failed: ungrounded: usage_rates.per transaction (ecommerce).unit_price_usd = 0.05 does not appear in the page text

Loopsemail
No price signal found in the raw page

fewer than 2 price matches (found 0)

Meilisearchsearch
Attempts did not reproduce a plausible tier count

attempt 1 extracted 4 priced tiers, attempt 2 extracted 4 priced tiers (low confidence)

MongoDB Atlasdatabases
Extraction failed grounding or schema

attempt 1 failed: ungrounded: usage_rates.Atlas Data Lake - Virginia, US (us-east-1) - Data Storage per GB per Month.unit_price_usd = 0.048 does not appear in the page text; usage_rates.Atlas Data Lake - Oregon, US (us-west-2) - Data Storage per GB per Month.unit_price_usd = 0.048 does not appear in the page text; usage_rates.Atlas Data Lake - Ireland (eu-west-1) - Data Storage per GB per Month.unit_price_usd = 0.048 does not appear in the page text; usage_rates.Atlas Data Lake - London, England (eu-west-2) - Data Storage per GB per Month.unit_price_usd = 0.0501 does not appear in the page text; usage_rates.Atlas Data Lake - Frankfurt, Germany (eu-central-1) - Data Storage per GB per Month.unit_price_usd = 0.0511 does not appear in the page text; usage_rates.Atlas Data Lake - Mumbai, India (ap-south-1) - Data Storage per GB per Month.unit_price_usd = 0.0522 does not appear in the page text; usage_rates.Atlas Data Lake - Singapore (ap-southeast-1) - Data Storage per GB per Month.unit_price_usd = 0.0522 does not appear in the page text; usage_rates.Atlas Data Lake - Sydney, Australia (ap-southeast-2) - Data Storage per GB per Month.unit_price_usd = 0.0522 does not appear in the page text, attempt 2 failed: ungrounded: tiers.Dedicated (M20).monthly_price_usd = 144 does not appear in the page text; tiers.Dedicated (M30).monthly_price_usd = 388.8 does not appear in the page text; usage_rates.Atlas Data Lake Storage per GB per month (Virginia, Oregon, Ireland).unit_price_usd = 0.048 does not appear in the page text; usage_rates.Atlas Data Lake Storage per GB per month (London).unit_price_usd = 0.0501 does not appear in the page text; usage_rates.Atlas Data Lake Storage per GB per month (Frankfurt).unit_price_usd = 0.0511 does not appear in the page text; usage_rates.Atlas Data Lake Storage per GB per month (Mumbai, Singapore).unit_price_usd = 0.0522 does not appear in the page text; usage_rates.Atlas Data Lake Storage per GB per month (Sydney).unit_price_usd = 0.0522 does not appear in the page text

Neondatabases
Attempts did not reproduce a plausible tier count

attempt 1 extracted 1 priced tier, attempt 2 extracted 1 priced tier

Paddlepayments
Attempts did not reproduce a plausible tier count

attempt 1 extracted 0 priced tiers, attempt 2 extracted 0 priced tiers

PostHogobservability
Attempts did not reproduce a plausible tier count

attempt 1 extracted 2 priced tiers, attempt 2 extracted 1 priced tier

Prismadata-tooling
Extraction failed grounding or schema

attempt 1 failed: ungrounded: usage_rates.Prisma Accelerate operations (Starter plan, per 1,000).unit_price_usd = 0.018 does not appear in the page text; usage_rates.Prisma Accelerate operations (Business plan, per 1,000).unit_price_usd = 0.006 does not appear in the page text; usage_rates.Prisma Accelerate cache tag invalidations (Business plan, per 1,000).unit_price_usd = 0.006 does not appear in the page text, attempt 2 failed: ungrounded: usage_rates.Prisma Accelerate operations (Starter).unit_price_usd = 0.018 does not appear in the page text; usage_rates.Prisma Accelerate operations (Business).unit_price_usd = 0.006 does not appear in the page text; usage_rates.Prisma Accelerate cache tag invalidations (Business).unit_price_usd = 0.006 does not appear in the page text

Qdrantvector-stores
No price signal found in the raw page

fewer than 2 price matches (found 0)

Railwayhosting
Extraction failed grounding or schema

attempt 1 failed: ungrounded: tiers.Free Trial.monthly_price_usd = 0 does not appear in the page text; usage_rates.Volumes.unit_price_usd = 6e-8 does not appear in the page text, attempt 2 failed: ungrounded: usage_rates.Volumes.unit_price_usd = 6e-8 does not appear in the page text; tiers.Free Trial.is_free = true but monthly_price_usd = null (free tiers must price at 0)

SendGridemail
No price signal found in the raw page

fewer than 2 price matches (found 0)

Stripepayments
Extraction failed grounding or schema

attempt 1 extracted 0 priced tiers, attempt 2 failed: ungrounded: usage_rates.Manually entered card transaction.unit_price_usd = 0.005 does not appear in the page text; usage_rates.International card transaction.unit_price_usd = 0.015 does not appear in the page text; usage_rates.Currency conversion fee.unit_price_usd = 0.01 does not appear in the page text; usage_rates.Klarna transaction.unit_price_usd = 0.0599 does not appear in the page text; usage_rates.ACH Direct Debit transaction.unit_price_usd = 0.008 does not appear in the page text; usage_rates.Stablecoin transaction.unit_price_usd = 0.015 does not appear in the page text; usage_rates.Stablecoin promotional rate.unit_price_usd = 0.008 does not appear in the page text; usage_rates.Payment optimization for custom pricing.unit_price_usd = 0.002 does not appear in the page text; usage_rates.Currency conversion fee minimum.unit_price_usd = 0.02 does not appear in the page text; usage_rates.Instant Payouts.unit_price_usd = 0.015 does not appear in the page text; usage_rates.Currency conversion in balance.unit_price_usd = 0.005 does not appear in the page text; usage_rates.Rate locking.unit_price_usd = 0.0007 does not appear in the page text; usage_rates.In-person international card transaction.unit_price_usd = 0.015 does not appear in the page text; usage_rates.Platform revenue share fee.unit_price_usd = 0.0025 does not appear in the page text; usage_rates.Debit card payout percentage.unit_price_usd = 0.0075 does not appear in the page text; usage_rates.Cross-border payout fee percentage.unit_price_usd = 0.0025 does not appear in the page text; usage_rates.FX fee percentage.unit_price_usd = 0.005 does not appear in the page text; usage_rates.Cross-border transaction.unit_price_usd = 0.01 does not appear in the page text; usage_rates.Billing volume fee.unit_price_usd = 0.007 does not appear in the page text; usage_rates.Invoice generation.unit_price_usd = 0.004 does not appear in the page text; usage_rates.Managed Payments transaction.unit_price_usd = 0.035 does not appear in the page text; usage_rates.Invoicing per paid invoice.unit_price_usd = 0.004 does not appear in the page text

Stytchauth
Extraction failed grounding or schema

attempt 1 failed: ungrounded: usage_rates.Monthly Active Users (beyond 10,000 included).unit_price_usd = 0.02 does not appear in the page text; usage_rates.Device fingerprints (beyond 10,000 included).unit_price_usd = 0.005 does not appear in the page text, attempt 2 failed: ungrounded: usage_rates.Additional monthly active users.unit_price_usd = 0.02 does not appear in the page text; usage_rates.Device fingerprints.unit_price_usd = 0.005 does not appear in the page text

Typesensesearch
Attempts did not reproduce a plausible tier count

attempt 1 extracted 0 priced tiers (low confidence), attempt 2 extracted 0 priced tiers (low confidence)

Weaviatevector-stores
Extraction failed grounding or schema

attempt 1 failed: ungrounded: usage_rates.SNOWFLAKE ARCTIC-EMBED-M-V2.0.unit_price_usd = 0.04 does not appear in the page text, attempt 2 failed: ungrounded: usage_rates.SNOWFLAKE ARCTIC-EMBED-M-V2.0.unit_price_usd = 0.04 does not appear in the page text

WorkOSauth
Attempts did not reproduce a plausible tier count

attempt 1 extracted 19 priced tiers, attempt 2 extracted 7 priced tiers

Xatadatabases
Extraction failed grounding or schema

attempt 1 failed: ungrounded: tiers.Open Source.monthly_price_usd = 0 does not appear in the page text, attempt 2 failed: ungrounded: tiers.Open Source.is_free = true but monthly_price_usd = null (free tiers must price at 0)

License and citation

Licensed CC BY 4.0 — reuse it anywhere, with attribution.

Citation

Bellwether. Developer-infrastructure pricing archive [dataset]. https://bellwether-nicholas-projects-cdfeb046.vercel.app/data/

BibTeX

@misc{bellwether,
  title  = {Bellwether: developer-infrastructure pricing archive},
  author = {{Bellwether}},
  url    = {https://bellwether-nicholas-projects-cdfeb046.vercel.app/data/},
  note   = {CC BY 4.0}
}