Sources Per Provider
Every price in the index traces to exactly one of the following official vendor sources — no third-party pricing aggregator, benchmark site, or reseller listing is ever used as a source of truth:
| Provider | Source | Format |
|---|---|---|
| Lambda | lambda.ai/pricing | Static HTML price table |
| CoreWeave | coreweave.com/pricing | Static HTML price table (priced per 8-GPU instance; normalized by dividing by GPU count) |
| RunPod | runpod.io/pricing | Static HTML price table, Secure Cloud tier |
| GCP | cloud.google.com — Accelerator-optimized VM pricing | Static HTML price table (on-demand, Spot, and 1yr/3yr Committed Use Discount columns) |
| Azure | Azure Retail Prices API | Unauthenticated public JSON API, queried per armSkuName + armRegionName |
| AWS | aws.amazon.com/ec2/capacityblocks/pricing | Static HTML price table — EC2 Capacity Blocks for ML reservation pricing only (6 SKUs); regular on-demand and Spot pricing still not sourced this edition, see What's Excluded |
Every row in the underlying dataset carries its own source URL and a "checked" date recorded at build time — visible in the full pricing table on the index page itself, not just in this summary.
How Normalization Works
The index's unit is USD per GPU-hour. Two normalization cases apply:
- Already per-GPU. Lambda's Instances price table, RunPod's Pods price table, and GCP's T4 GPU-attachment table all publish a single-GPU price directly (Lambda's table is explicitly labeled "Price/GPU/Hr"). These are used as-is.
- Multi-GPU instance, divided by GPU count. CoreWeave's on-demand and spot prices are published per 8-GPU instance (except its 1-GPU GH200 SKU); GCP's a3-highgpu-8g, a2-highgpu-8g, and g2-standard-96 machine types price the whole VM; Azure's ND96isr_H100_v5 and ND96asr_v4 SKUs price the whole 8-GPU VM. In every one of these cases, the published on-demand, spot, and committed-use price is divided by the GPU count in that SKU to produce the normalized per-GPU rate shown in the index.
Committed-use pricing on Azure is published as a total contract price for the reservation term (for example, a specific dollar figure for "1 Year" or "3 Years"), not an hourly rate. To make it comparable, that total is divided by the number of hours in the term (8,760 hours for 1 year; 26,280 hours for 3 years) to produce an hourly-equivalent, then normalized per GPU the same way as on-demand.
Region Selection
Each provider uses one representative, explicitly named region or tier — chosen for consistency within that provider, not necessarily the cheapest region available:
| Provider | Region / scope used | Why |
|---|---|---|
| Azure | eastus | Standard US primary region; matches the region used for the Azure H100 SKU cited in GPU Cost Optimization. |
| GCP | us-central1 (Iowa) | Default region shown on GCP's own accelerator-optimized pricing page. |
| CoreWeave | North America | CoreWeave's pricing page publishes separate North America and Europe tables; North America is used for consistency with the US-centric regions used elsewhere in the index. |
| Lambda | Single global price list | Lambda's Instances pricing page does not expose a region selector — one price list applies. |
| RunPod | Secure Cloud tier | RunPod's Pods pricing table is not region-differentiated on the public pricing page; Secure Cloud (rather than Community Cloud) is used per FOF-003's build scope. |
Because each provider uses a single fixed region, cross-provider comparisons in this index are not adjusted for regional price variation within a given provider — a GPU model may be cheaper or more expensive in a different region of the same cloud.
One representative, named region/scope per provider for on-demand pricing, with two documented exceptions: Lambda = single global on-demand price list (no region selector on the pricing page); CoreWeave = North America; RunPod = Secure Cloud tier (pricing page is not region-differentiated); GCP = us-central1 (Iowa), the default region shown on the accelerator-optimized pricing page; Azure = eastus for the H100 and A100 rows. Exception 1: Azure's MI300X row uses canadacentral instead of eastus, because the MI300X SKU is not offered in eastus (zero items returned from the Azure Retail Prices API) -- canadacentral is MI300X's primary GA region on Azure. Exception 2: AWS EC2 Capacity Blocks pricing is not region-uniform on the vendor's own pricing page (prices differ by instance family and region), so each AWS row states its own region individually rather than sharing one representative region across all AWS rows -- US East (N. Virginia) is used wherever the vendor page offers it, falling back to US East (Ohio) for the one SKU (p5e.48xlarge) where N. Virginia is not listed. See the methodology page for full detail.
What's Excluded
Three categories are deliberately left out of the index, each for a documented reason:
- AWS — Capacity Blocks in, on-demand/Spot still out. This edition adds 6 AWS EC2 Capacity Blocks for ML reservation pricing rows (checked 2026-07-20) — a distinct, separately-published, static-HTML price list. Regular AWS EC2 on-demand and Spot pricing remains excluded: AWS's standard EC2 on-demand and Spot pricing pages (aws.amazon.com/ec2/pricing) remain JavaScript-rendered and return no usable price data to a static content fetch; the unauthenticated bulk pricing offer file (pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonEC2/current/...) is gigabyte-scale and not retrievable in a single web_fetch call; a smaller AWS-hosted metered-unit-maps endpoint was tested directly and confirmed to contain only instance attribute metadata and internal rateCode identifiers, not actual prices.
- AWS G6/G5 instance families (all pricing modes). G6 and G5 (L4- and A10G-based) instance families are not part of the EC2 Capacity Blocks for ML program -- the live Capacity Blocks pricing page (aws.amazon.com/ec2/capacityblocks/pricing/, fetched 2026-07-20) only lists P5/P5e/P5en/P4d/P4de, the P6 family (P6e/P6-B300/P6-B200), and Trn1/Trn2. No other live, official, unauthenticated AWS source for G6/G5 pricing was found this session, so they remain fail-closed dropped in their entirety.
- Vast.ai and other GPU marketplaces. Vast.ai is a peer-to-peer GPU rental marketplace: prices vary by individual listing and host, not by a single vendor-published rate, so there is no stable number to normalize. It is intentionally excluded from the index and is only referenced qualitatively elsewhere on FinOpsForge as "marketplace, pricing varies."
- Negotiated / enterprise pricing. Every price in this index is public list pricing. Enterprise agreements, private pricing, and volume discounts negotiated directly with a vendor are not reflected and are typically lower than the list prices shown here.
Individual SKUs are also dropped on a case-by-case fail-closed basis when a specific price cannot be live-verified — for example, a GPU model advertised in vendor marketing copy but not present on the current live pricing page, or a SKU not offered in the provider's chosen representative region. Each such drop is documented in the underlying dataset rather than silently omitted.
Refresh Cadence
The index is intended to be refreshed on a monthly cadence: the same data collection and generator process is re-run against each provider's live pricing source, replacing the dataset and regenerating both this page and the index page. The "Last updated" date on the index page always reflects the most recent refresh. Because GCP notes that its own Spot prices can change up to once every 30 days, a monthly refresh keeps the index within one pricing cycle of current for the most volatile purchasing mode covered.