The public dataset
| Current rental quotes | 220 | one per provider, GPU, price type and region, each with its source URL and the time it was read |
|---|---|---|
| GPU models | 20 | specs, coverage, retail median where three or more sellers carry the card |
| Providers | 21 scraped, 27 listed | hyperscalers, specialist clouds and one marketplace |
| Weekly history | 88 weeks | 1 from our own scrape, 87 reconstructed from the SkyPilot catalog, kept apart |
| Per-model series | 18 models | 1401 weekly points with the cheapest listed rate and who listed it |
| Files | 7 | 5 JSON, 2 CSV — no key, no rate limit |
| Updated | hourly | rental prices every hour when a price moved, retail weekly, history weekly |
| License | CC BY 4.0 | attribution to “GPU Economy” with a link to the page or file used |
Everything on this site is also a file. Seven files, built with the site from the same data the pages show, so a number here is the number on the page. All of them are published under CC BY 4.0: use, copy and redistribute with attribution to “GPU Economy” and a link to the page or file you used. Cite the linked source for a price itself, and cite us for the normalization, the index and the comparisons. No key, no rate limit.
From a script, send a User-Agent header. Any value works: curl, requests, Node and Go clients are served as they are. The hosting platform, though, refuses Python’s built-inurllib when it sends its default agent (Python-urllib/3.x): HTTP 403, “error code: 1010”. That check sits above the settings we control, so with the standard library, name your client:
import json, urllib.request
req = urllib.request.Request('https://gpueconomy.com/prices.json', headers={'User-Agent': 'my-analysis/1.0'})
prices = json.load(urllib.request.urlopen(req))
print(prices['count'], 'quotes, data updated', prices['data_updated_at'])Data updated . Two sources are labelled wherever they appear: gpueconomy is our own hourly scrape (from the week of September 7, 2026);skypilot-catalog is a second-hand history reconstructed from the public SkyPilot catalog, with a commit permalink per row. They are never merged. How the numbers are made: methodology.
Slices
The price file also ships narrowed, so a reader who wants one card or one provider does not fetch all220 rows. Same fields, fewer rows, same license:
| URL | Contains | Files |
|---|---|---|
/gpu/{gpu_id}/prices.json | every current rate for one card, across providers — e.g. /gpu/h100-sxm/prices.json | 20 |
/providers/{provider_id}/prices.json | every current rate at one provider, across cards — e.g. /providers/runpod/prices.json | 27 |
The ids are the ones in gpus.json and providers.json, and they are the same ids in the page URLs — so a slice URL can be derived from a page URL without a lookup. There is no query API and no key: the site is static files on a CDN, and a filter parameter would need a runtime that can be down while the pages are up.
Receipts for the Price Index
Every published week of the Price Index has a receipt: one CSV row per quote that entered that week’s value — provider, region, usd_per_gpu_hour, scope, source URL, read time — at /price-index/receipts/{YYYY-Www}.csv, for example /price-index/receipts/2026-W37.csv (provisional). A closed week’s receipt never changes. How to turn one back into the published number, with the command: reproduce the index. Each week in price-index.json carries its receipt URL.
/prices.json JSON
Every current rental quote: one row per provider, GPU, price type and region, normalized to USD per GPU per hour, with the listed price it came from and its source URL. The same rows and fields as CSV: /prices.csv.
Updated: Hourly, when a price moved. · Size now: 220 quotes, 21 providers, 20 GPUs.
| Field | Meaning |
|---|---|
provider, provider_id, gpu, gpu_id | names and slugs; provider_page and gpu_page link back here |
price_type | on_demand | spot | reserved |
price_scope | instance | gpu_only | marketplace_floor | advertised_from - what the figure covers |
region | the provider’s own partition label (a geography, a data center, or a tier); null = global |
usd_per_gpu_hour | the normalized, comparable figure |
listed_price_usd_hour, listed_unit, gpu_count | the quote as listed (per_gpu or per_node) and the divisor |
listed_currency, listed_price_hour, fx_rate, fx_date | for EUR listings: the listed EUR figure and the ECB rate and date behind the USD one |
source_url, scraped_at | where and when the price was read |
listed_since, listed_since_first_read | since when the provider has listed this exact figure (in the listed currency, same GPU count), from our own hourly reads; listed_since_first_read = true when it has not changed since our first read, so the real age may be longer |
last_confirmed_at, status | when the price was last read successfully, and live | unconfirmed | stopped: live = within 48 h of data_updated_at, unconfirmed = 48 h to 7 days, stopped = older. The site computes its figures from live rows only |
/price-index.json JSON
The Cloud GPU Price Index: current value with its constituents (each linked), the weekly series with vintage and the base-100 index, and the reconstructed historical series.
Updated: Hourly; the running week is provisional, closed weeks are final. · Size now: 1 weeks of our own series from September 7, 2026, 87 reconstructed weeks from January 6, 2025.
| Field | Meaning |
|---|---|
current.usd_per_gpu_hour, quotes, providers, constituents[] | this week’s median and every quote in it, with source_url |
current.status, current.withheld_reason | published | withheld. When withheld, usd_per_gpu_hour is null and withheld_reason says why: cause (too_few_providers | not_confirmed_48h), the sentence the page prints, providers_confirmed and providers_required, and each provider not confirmed within 48 h with last_confirmed_at |
series[].week_start, usd_per_gpu_hour, quotes, providers, vintage, index_base100 | one row per published ISO week; vintage = provisional | final |
withheld[].week_start, vintage, providers_confirmed, providers_required | weeks since the series began that the coverage guard suppressed; they have no row in series or in price-index.csv |
exclusion_rules | why a quote is left out of the index, by code: not_confirmed_48h, marketplace_floor, eur_listing |
historical_series.points[] | same shape, reconstructed from the SkyPilot catalog; a separate panel, never merged |
method, index_base100_method, min_providers | the rules, in words |
/price-index.csv CSV
The weekly series of our own index only.
Updated: Hourly. · Size now: 1 weeks.
| Field | Meaning |
|---|---|
week_start, usd_per_gpu_hour, quotes, providers, vintage, index_base100 | one row per published ISO week. A week with no row was withheld by the coverage guard, not lost: price-index.json lists it under withheld[] with its provider count |
/price-index-history.csv CSV
The reconstructed H100 series from the public SkyPilot catalog, kept in its own file.
Updated: Weekly, the Monday after a week closes. · Size now: 87 weeks.
| Field | Meaning |
|---|---|
week_start, usd_per_gpu_hour, quotes, providers, index_base100, source | source is always skypilot-catalog |
/history.json JSON
Weekly history for every model with enough weeks: median and cheapest listed on-demand rate per week, who listed the cheapest and where, from both sources, labelled.
Updated: Hourly for our own series; weekly for the reconstructed one. · Size now: 18 models, 1401 weekly points.
| Field | Meaning |
|---|---|
index, historical_index | the two index series, as in price-index.json |
models[].gpu_id, series[].source | source = gpueconomy | skypilot-catalog |
series[].weeks[].week_start, providers, median_usd_per_gpu_hour, min_usd_per_gpu_hour | per ISO week; median of each provider’s cheapest region |
min_provider, min_region, min_source_url | who listed the cheapest rate that week, and where to verify it |
/providers.json JSON
Every provider tracked or listed: type, how its prices are read, what its region label means, and its current contribution.
Updated: With every site build. · Size now: 27 providers, 21 scraped.
| Field | Meaning |
|---|---|
id, name, type | type = hyperscaler | specialist | marketplace |
website, pricing_page, source_kind | source_kind = api | html | js_rendered | console_only | quote_only |
regions, scraped, models_tracked, current_quotes, notes, page |
/gpus.json JSON
Every GPU model tracked: specs, current coverage, the 3+-seller retail median, and the manufacturer list price where the vendor publishes one.
Updated: With every site build. · Size now: 20 models.
| Field | Meaning |
|---|---|
id, name, vendor, architecture, vram_gb, form_factor | specs |
providers_listing, current_quotes | coverage now |
retail_median_new_usd, retail_sellers | null until three sellers carry the card |
manufacturer_list_price_usd, manufacturer_list_price_source | consumer cards only; datacenter parts have no published price |
page, history_page | history_page is null until the model has eight weeks of data |
Reading the numbers
- usd_per_gpu_hour is the only cross-provider comparable figure. A node price is divided by its GPU count; a per-second rate is multiplied by 3,600; a EUR listing is converted at the ECB rate stored next to it.
- price_scope says what a figure covers: a full instance, the GPU line item alone, a marketplace floor (median of the five cheapest verified asks), or an advertised “from” rate. Compare like with like.
- The index is a level (the dollar median, printed with its panel size) and a change (the base-100 index, which moves only when a listed price changes). Cite the median for “what it costs” and the index for “how it moved”.
- Vintage: the running week is provisional and is recomputed every hour; a week that has closed is final and never recomputed.
Cite this page
Published under CC BY 4.0: use and redistribute with attribution and a link. Cite the linked source for a price itself, and cite us for the normalization, the index and the comparison. For a single figure, cite the page it appears on; for bulk use, cite this page and name the file.
| Plain | GPU Economy, "Public GPU pricing dataset", September 12, 2026. https://gpueconomy.com/data |
|---|---|
| Markdown | [GPU Economy, "Public GPU pricing dataset" (September 12, 2026)](https://gpueconomy.com/data) |
| APA | GPU Economy. (2026-09-12). Public GPU pricing dataset. Retrieved from https://gpueconomy.com/data |
Data updated: