On-demand pricing is the list price a provider charges for usage with no commitment: a published rate per unit, such as an instance-second, a gigabyte-month or a request, billed in arrears for the quantity used. There is no term, no upfront payment and nothing to cancel. That makes on-demand pricing the reference price on the bill: commitment discounts, spot prices and every reported saving are measured against it, and any usage no commitment covers pays it in full.
How it works
A line's amount is quantity times rate. Region, instance type, operating system and any bundled licence set the rate; the billing increment (the smallest unit in which run time is counted) and a minimum duration set the quantity. All three providers publish prices in US dollars; AWS and Azure state they exclude tax. How quantity, unit and rate form a line is covered in usage, rates and line items on a cloud invoice, and what drives a VM's rate in virtual machines and instance families.
AWS
Amazon EC2 bills On-Demand Instances by the hour or by the second, with a 60-second minimum, from launch until the instance is stopped or terminated. Per-second billing covers Linux, Windows, Windows with SQL Server, RHEL and Ubuntu Pro; SUSE Linux Enterprise Server is billed in full hours. Rates are on the pricing page and in the AWS Price List (Query API per SKU, Bulk API as JSON or CSV files per service and Region), which has no Spot prices. Where a price file and the pricing page differ, AWS documents that it charges the pricing page. In the Cost and Usage Report (CUR 2.0) every line carries the public rate in pricing_public_on_demand_rate and the amount at that rate in pricing_public_on_demand_cost; pricing_term separates On-Demand from Reserved.
Azure
The Azure Retail Prices API needs no sign-in and returns, per meter, retailPrice (the list price without discount), unitOfMeasure and type; on-demand rates have type Consumption, and VM meters are quoted per 1 Hour. According to the FAQ on the VM pricing page, Azure bills full minutes: a VM that ran for 6 minutes and 45 seconds is charged 6 minutes. A VM shut down from inside the operating system shows Stopped and keeps paying for its cores; only Stopped (Deallocated) ends the charge. Microsoft prices every service in US dollars, and the API returns other currencies for reference only. In the cost details, PayGPrice holds the meter's market price, UnitPrice the negotiated price, EffectivePrice the price actually paid, and PricingModel = OnDemand marks usage without a commitment.
Google Cloud
Compute Engine charges vCPUs, GPUs and memory for at least one minute, then per second. Uptime runs from start until the instance reaches STOPPING, so a VM in state RUNNING costs the same idle or busy. Compute Engine's pricing table carries the on-demand price in its Default column. Customers who pay in another currency pay the SKU prices in that currency. The Google Cloud Pricing API, in preview, returns public prices with an API key and contract prices per Cloud Billing account. The standard export to BigQuery carries cost_at_list beside cost, and price.list_price from 2025-07-15; the pricing export holds list_price with its tiers in tiered_rates.
| Provider | Billing increment | Price source | List price in the export |
|---|---|---|---|
| AWS, Amazon EC2 | second, 60-second minimum; SUSE by the hour | pricing page, AWS Price List | CUR 2.0: pricing_public_on_demand_rate |
| Azure, Virtual Machines | full minute; rate per 1 Hour | pricing page, Azure Retail Prices API | cost details: PayGPrice |
| Google Cloud, Compute Engine | second, 1-minute minimum | pricing page, Google Cloud Pricing API | standard export: cost_at_list, price.list_price |
FOCUS
The FOCUS specification carries the price-list value in ListUnitPrice, converted to the billing currency and with no discount applied. PricingCategory = Standard covers charges the billing account pays on its contracted terms; negotiated discounts and volume tiers fall under it, spot and commitment rates do not. Standard is therefore not the list price. The mapping per provider is in FOCUS columns and the providers' mapping.
What it means for your cost
In the export, on-demand usage is an ordinary line item, and the list price fields sit beside it even when a discount applied. That gives two values for one quantity: list price times quantity is the value with no agreement at all, and effective cost is what remains after discounts and commitments. The difference is the saving that commitments and contracts produce; list, billed, effective and amortized cost sets out the measures.
A negotiated rate is not a list price. Under private pricing an account pays its own rate, which Azure shows in UnitPrice and Google in price.effective_price (the amount in cost; see enterprise agreements and private pricing). A check against the pricing page then shows a gap that is not an error. Likewise, a US dollar rate rarely matches an invoice in euros or pounds, because exchange rate and tax come after it (invoice currency and exchange rates).
In a cost report, the share of usage at on-demand rates is the figure any review of a commitment starts from. Cost Explorer filters it by Purchase option (On-Demand Instances, Reserved Instances, Spot Instances), the Azure cost details by PricingModel, FOCUS by PricingCategory. Base load that runs at on-demand rates month after month is what commitments such as AWS Reserved Instances address; load that tolerates interruption is what spot capacity addresses. Short or volatile load stays on demand, where the fine increment charges only the run time. Without a purchase, the rate per unit falls only through tiered pricing and automatic usage discounts.
Where it goes wrong
- Stopped but not deallocated. Symptom: an Azure VM shows Stopped and still appears with its full quantity in the export. Cause: only Stopped (Deallocated) releases the cores; a shutdown from the operating system keeps them allocated.
- Short runs at the minimum. Symptom: on AWS and Google, many short jobs cost more than their run time in seconds suggests; on Azure they do not. Cause: AWS charges at least 60 seconds, Google at least one minute and SUSE on Amazon EC2 full hours; Azure, by contrast, charges only full minutes and drops the remaining seconds.
- Rate from the wrong source. Symptom: a recalculated saving does not match the invoice. Cause: a euro price list was taken for the billed rate, although Microsoft returns non-USD prices for reference only and AWS charges the pricing page where a price file differs.
- Highest tier as the reference. Symptom: the on-demand reference for storage or data transfer does not match the rate paid. Cause: for tiered SKUs
pricing_public_on_demand_rateshows the rate of the highest tier, not the tier reached. - Idle in state RUNNING. Symptom: Google VMs without load cost the full rate. Cause: Compute Engine counts uptime until STOPPING, whatever the utilisation.
Example
On 2026-10-16 the pricing pages list these on-demand rates in US dollars per hour, excluding tax for AWS and Azure, for one machine type with 2 vCPUs and 8 GiB of memory per provider in Frankfurt:
| Provider | Type | Region | Operating system | Rate per hour |
|---|---|---|---|---|
| AWS | m7i.large | Europe (Frankfurt), eu-central-1 | Linux | USD 0.12075 |
| Azure | D2s v5 | Germany West Central | Ubuntu | USD 0.1150 |
| Google Cloud | n2-standard-2 | Frankfurt, europe-west3 | no premium image | USD 0.125124 |
The types match in vCPUs and memory, not in processor or performance.
Sources
Read on 2026-10-16. AWS Amazon EC2 On-Demand pricing, AWS Price List, CUR 2.0 pricing columns, filtering in Cost Explorer; Microsoft Azure Retail Prices API, Linux Virtual Machines pricing, Ingest cost details data, Understand usage details fields; Google Cloud VM instance pricing, General purpose VM pricing, Get Google Cloud pricing information, Structure of standard data export, Structure of pricing data export; FinOps Foundation FOCUS column library, List Unit Price, Pricing Category.