The GPU index
One number per crop per hour: the median rental price in USD per GPU-hour across three public quotes. Nothing in it needs an API key, so anyone can fetch the same books and get the same number.
Sources
| Source | Endpoint | Value used |
|---|---|---|
| Vast.ai | console.vast.ai/api/v0/bundles/ | Median of dph_total / num_gpus over rentable on-demand offers for the model |
| RunPod community | api.runpod.io/graphql gpuTypes | communityPrice |
| RunPod secure | same query | securePrice |
On Vast.ai, offers from verified hosts are used first. When a model has no verified offer that hour, every rentable offer is used, and the snapshot says so in vast.basis.
Method
- At minute :09 of each UTC hour the keeper fetches both books once.
- For each crop it takes the Vast.ai median, the RunPod community price and the RunPod secure price. A price of zero or a failed request drops that source and is noted in
dropped. - The index is the median of the remaining values, rounded to 4 decimals. With fewer than two values the crop gets no point that hour.
- The keeper posts
post(crop, hour, price, sources, raw). The contract storeskeccak256(raw)and refuses a second point for the same crop and hour.
The raw snapshot
The snapshot is compact JSON with every offer that went into the Vast.ai median, as [offerId, $/GPU-hour] pairs, and both RunPod prices:
{
"v": 1, "crop": "H100 SXM", "hour": 498077,
"vast": { "gpu_name": "H100 SXM", "basis": "verified",
"offers": [[50189142, 3.5962], ...], "median": 3.594 },
"runpod": { "id": "NVIDIA H100 80GB HBM3", "community": 2.69, "secure": 3.99 },
"dropped": [], "sources": 3, "index": 3.594
}It is served at /index/raw/<hash>.json. The site reads it from the post's calldata and checks the hash before answering, so the file cannot differ from what was posted.
Recompute a point
The verifier takes a hash, fetches the snapshot, hashes the bytes, rebuilds the median and compares it with the price stored on GpuIndex. The same module runs in Node:
import { verify } from "https://gpuacres.org/verifier/verify.mjs"
console.log(await verify("0x5c1e..."))
// { hashOk: true, recomputed: 2.69, posted: 2.69, match: true }