Measured · every input published

The Node Hour Index

One number per GPU class, in dollars per GPU-hour. It is not a model output and not an opinion — it is a vendor's own on-demand rate, read through a public API and normalised onto a canonical market. The query is below. Run it and you get the same numbers we do.

Live inputs

reading…
Provider SKUVRAMOn-demand $/h Spot $/hCanonical market
Reading provider rate cards…

How the number is made

1

Poll. The provider's public GraphQL endpoint is queried for every GPU type it sells, with the lowest on-demand and spot price for a single card. No API key is involved, so the call is reproducible by anyone.

2

Normalise. Vendors sell SKUs, not classes: H100 SXM, H100 NVL and H100 PCIe are three products. Each canonical market maps to an ordered list of SKU patterns and takes the first that is quoted, so the same physical class always resolves the same way.

3

Publish. The response is served with its fetch timestamp and the full unnormalised list, which is the table above. Nothing is smoothed, filtered or adjusted between the provider's number and the one shown.

4

Cache. Responses are cached 60 seconds at the edge and served stale for up to 10 minutes while revalidating, so a provider outage degrades the index instead of breaking it. A stale read is flagged as stale.

Reproduce it

curl -s -X POST https://api.runpod.io/graphql \ -H 'content-type: application/json' \ -d '{"query":"{ gpuTypes { displayName memoryInGb lowestPrice(input:{gpuCount:1}) { uninterruptablePrice minimumBidPrice } } }"}'

Or read our normalised form directly — it is a plain JSON endpoint with permissive CORS, free to poll: /api/prices

What this index is not, yet

It is single-source

Today every number comes from one provider. That makes it a working reference price, not a benchmark — a benchmark has to survive one vendor repricing. Adding vast.ai, Lambda and TensorDock, then trimming outliers across them, is the next piece of work.

It is unweighted

A rate card says what a vendor asks, not what anyone paid. A real benchmark weights by traded volume. We have no volume to weight by, and inventing one would defeat the point of the page you are reading.

It has no history

Every read is live; nothing is stored. So there is no chart of what an H100 hour cost last month, which is exactly the gap that makes compute pricing opaque in the first place. Storage is the first thing that gets built.

It is a floor, not a mid

The query asks for the lowest on-demand price a provider offers for one card. That is a defensible, stable definition, but it sits at the bottom of the distribution rather than the middle of it.