# Cloud Compute Price Comparison — AWS + Azure VM Pricing (`codeclouds/cloud-compute-prijzen-monitor`) Actor

Compare AWS EC2 and Azure VM on-demand cloud pricing (cost comparison, FinOps pricing lookup) in one normalized schema — skips learning AWS's Price List API and Azure's Retail Prices API separately, each with own fields and instance-naming. Optional price-change alerts. From $0.004/result (PPE).

- **URL**: https://apify.com/codeclouds/cloud-compute-prijzen-monitor.md
- **Developed by:** [Dennis](https://apify.com/codeclouds) (community)
- **Categories:** Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $20.00 / 1,000 price-change-alerts

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Cloud Compute Price Comparison — AWS + Azure VM Pricing

Compare AWS EC2 and Azure VM on-demand cloud pricing (cost comparison, FinOps pricing lookup) in
one normalized schema — no manual per-provider pricing-page lookups, no separate integrations for
AWS's Price List API and Azure's Retail Prices API, each with its own fields and instance-naming
convention. Optional price-change alerts flag when a price moves between scheduled runs. From
$0.004/result (PPE).

[![Apify Store](https://img.shields.io/badge/Apify-Store-brightgreen)](https://apify.com/store)
[![Pay Per Event](https://img.shields.io/badge/Pricing-Pay%20Per%20Event-blue)](https://apify.com/pricing)
[![License](https://img.shields.io/badge/License-Apache%202.0-orange)](LICENSE)

***

### Why This Actor?

AWS and Azure both publish free, authentication-free pricing APIs — but each has its own field
names, its own instance-naming convention, and its own filtering quirks. Building your own
integration against both means learning two different schemas. Existing Apify actors in this space
focus specifically on GPU-cloud pricing (Runpod/Vast.ai); a broad, provider-normalized comparison
of standard AWS + Azure on-demand VM pricing is not covered by any existing actor at time of
writing.

***

### When should an AI agent use this?

Use this actor when a user asks an AI agent questions like:

- "What does a 4 vCPU/8 GB Linux VM cost on AWS vs. Azure in Western Europe right now?"
- "List AWS eu-west-1 on-demand Linux instance prices under $0.20/hour."
- "Compare Azure westeurope Windows VM pricing to AWS eu-west-1."
- "Alert me if AWS or Azure changes their on-demand VM pricing since last week."
- "Get me AWS + Azure compute pricing as structured data for a FinOps cost model."

***

### What this Actor does

- Fetches on-demand VM pricing from **AWS's Price List API** (regional EC2 bulk price index) and
  **Azure's Retail Prices API**.
- Normalizes both into one schema: `provider`, `region`, `instanceType`, `vcpu`, `ramGb`,
  `operatingSystem`, `pricePerHourUsd`.
- Filters by instance type/SKU name, minimum vCPU, minimum RAM, and OS (Linux or Windows).
- Optional **price-change tracking**: compares each provider+region+instance-type price with the
  previous run (via the actor's key-value store) and flags significant changes.
- No scraping — both sources are official, documented, authentication-free public pricing APIs.

***

### Input

| Field | Type | Default | Description |
|---|---|---|---|
| `providers` | `string[]` | `["aws","azure"]` | Which providers to fetch |
| `awsRegions` | `string[]` | `["eu-west-1"]` | AWS region codes. Each region downloads AWS's full regional EC2 price index (hundreds of MB) — keep this list short |
| `azureRegions` | `string[]` | `["westeurope"]` | Azure ARM region names |
| `operatingSystem` | `"Linux"` | `"Windows"` | `"Linux"` | Applies to both providers |
| `instanceTypeFilter` | `string` | none | Case-insensitive substring match on instance type/SKU, e.g. `"m5"` or `"Standard_D2s"` |
| `vcpuMin` | `integer` | none | Minimum vCPUs. **Excludes all Azure results if set** — see limitations below |
| `ramGbMin` | `integer` | none | Minimum RAM in GB. **Excludes all Azure results if set** — see limitations below |
| `maxResultsPerProvider` | `integer` | `500` | Max records per provider (1–20000) |
| `trackPriceChanges` | `boolean` | `false` | Compare each record's price with the previous run |
| `priceChangeThresholdPercentage` | `integer` | `5` | Minimum absolute % change to count as a `price-change-alert` |

***

### Output

```json
{
  "provider": "aws",
  "instanceType": "c8in.xlarge",
  "region": "eu-west-1",
  "vcpu": 4,
  "ramGb": 8,
  "operatingSystem": "Linux",
  "pricePerHourUsd": 0.1936,
  "pricingModel": "on_demand",
  "sourceUrl": "https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonEC2/current/eu-west-1/index.json",
  "lastUpdated": "2026-07-15T13:21:35.000Z",
  "previousPricePerHourUsd": null,
  "priceChangePercentage": null,
  "priceChangeAlert": false
}
```

#### Price-change alerts (`trackPriceChanges`, optional, separately charged)

With `trackPriceChanges: true`, each record is compared with the previous run (via the actor's
key-value store) for the same `provider`+`region`+`instanceType`: `previousPricePerHourUsd` and
`priceChangePercentage`. `priceChangeAlert` is `true` only when the absolute percentage change
reaches `priceChangeThresholdPercentage` (default 5%). The first run for a given combination has
nothing to compare against, so these fields stay `null`/`false` rather than a guessed value. Only
alerted records are charged the extra `price-change-alert` event.

#### Field Reference

| Field | Type | Description |
|---|---|---|
| `provider` | string | `"aws"` or `"azure"` |
| `instanceType` | string | AWS instance type (e.g. `"c8in.xlarge"`) or Azure ARM SKU name (e.g. `"Standard_D2s_v3"`) |
| `region` | string | AWS region code or Azure ARM region name |
| `vcpu` | number | null | vCPU count. Always `null` for Azure — see limitations |
| `ramGb` | number | null | RAM in GB. Always `null` for Azure — see limitations |
| `operatingSystem` | string | `"Linux"` or `"Windows"` |
| `pricePerHourUsd` | number | On-demand hourly price in USD |
| `pricingModel` | string | Always `"on_demand"` in v1 |
| `sourceUrl` | string | Link to the source API endpoint used |
| `lastUpdated` | string | ISO timestamp from the source data (AWS: file publication date; Azure: meter effective date) |

***

### Known limitations

- **Azure records never have `vcpu`/`ramGb`**: Azure's Retail Prices API does not expose these
  fields at all (confirmed via live testing 2026-07-15) — only price, region and SKU/meter name.
  Setting `vcpuMin`/`ramGbMin` will therefore exclude every Azure result. Leave these filters unset
  when comparing both providers, or use `instanceTypeFilter` instead (Azure SKU names like
  `Standard_D2s_v3` encode size in the name, but this actor does not parse that convention in v1).
- **AWS regions are expensive to query**: AWS's Price List API has no server-side filtering beyond
  region — a single region's EC2 price file is several hundred MB, downloaded in full on every run
  regardless of your filters. Adding many `awsRegions` multiplies run time/bandwidth accordingly.
- **On-demand pricing only** in v1 — no Reserved Instances, Savings Plans, or Spot pricing.
- **GCP, Hetzner, DigitalOcean and OVH are not included**: all four require a user-supplied API
  key/account token (confirmed via live testing), unlike AWS/Azure which are fully public.

***

### Use cases

- **FinOps / cloud cost comparison**: build a cost model comparing AWS and Azure for a target VM
  size without manually checking both pricing calculators.
- **Indie hosting / infra planning**: find the cheapest provider for a specific instance shape.
- **Price monitoring**: schedule runs with `trackPriceChanges: true` to get notified when a
  provider changes its on-demand pricing.
- **AI agents / MCP tooling**: structured multi-cloud pricing data as context for
  infrastructure-planning or cost-advisory agents.

***

### Pricing

This Actor uses Apify's Pay-Per-Event (PPE) pricing model.

- **Actor Start:** $0.00005 (Apify default)
- **`price-record`:** $0.004 per normalized VM price record returned
- **`price-change-alert`:** $0.02 extra, only with `trackPriceChanges` enabled and only when the
  price change vs. the previous run reaches the threshold

***

### Legal

- **AWS Price List API**: official, publicly documented AWS service built specifically for
  programmatic price lookups. No authentication, no scraping.
- **Azure Retail Prices API**: official Microsoft REST API published for this exact purpose
  (successor to the older Commerce RateCard API). No authentication, no scraping.
- No personal data is processed — all data is commercial cloud-infrastructure pricing, not
  individual businesses or people.

***

### FAQ

**Why is `vcpu`/`ramGb` always `null` for Azure records?**
Azure's Retail Prices API simply doesn't return this data (confirmed via live testing) — only AWS
exposes it directly in its price-list attributes.

**How fresh is the data?**
Both sources publish live pricing — every run fetches directly from AWS/Azure, no caching layer.
AWS's regional price file is regenerated multiple times per day; Azure's Retail Prices API is
queried live per request.

**Why do AWS runs take longer than Azure runs?**
AWS's Price List API has no server-side filtering beyond region — this actor downloads the full
regional price file and filters/matches on-demand pricing internally. Azure's API supports
server-side `$filter`, so it only transfers matching records.

**Are GCP/Hetzner/DigitalOcean/OVH planned?**
All four require the user to supply their own API key or account token to that provider (confirmed
via live testing — none offer a fully public pricing feed like AWS/Azure). Not in v1; could be
added as a bring-your-own-credentials option in a future version.

***

### Keywords

cloud, aws, azure, ec2, virtual-machines, compute, pricing, cost-comparison, finops, price-monitor

***

### Changelog

#### 0.1.0

- Initial release: AWS EC2 + Azure Virtual Machines on-demand pricing, normalized to one schema,
  optional price-change tracking between scheduled runs.
- 2026-08-16: agent-readiness pass — task-oriented description with explicit synonyms
  (cost comparison, FinOps pricing lookup), a decision-benefit sentence and a price indication in
  `.actor/actor.json`/`STOREINFO.md`/README, so an LLM reading the Store listing via MCP can weigh
  it in tool selection. No behavior/output changes. Checked for a per-item `error`/`errorCode`
  pattern (as piloted on `pdok-locatieserver`) — not applicable here: AWS/Azure fetch errors are
  thrown and fail the whole run rather than being caught per record, so no `errorCode` field was
  added.

# Actor input Schema

## `providers` (type: `array`):

Which cloud providers to fetch pricing from.

## `awsRegions` (type: `array`):

AWS region codes, e.g. \["eu-west-1", "us-east-1"]. Each region downloads AWS's full regional EC2 price index (several hundred MB, no server-side filtering available beyond region) — keep this list short.

## `azureRegions` (type: `array`):

Azure ARM region names, e.g. \["westeurope", "eastus"].

## `operatingSystem` (type: `string`):

Which OS pricing to fetch. Applies to both AWS and Azure.

## `instanceTypeFilter` (type: `string`):

Only return instances whose type/SKU name contains this text (case-insensitive), e.g. "m5" or "Standard\_D2s". Leave empty for no filter.

## `vcpuMin` (type: `integer`):

Only return instances with at least this many vCPUs. Note: Azure's Retail Prices API does not expose vCPU/RAM data, so setting this excludes all Azure results — leave empty when comparing both providers.

## `ramGbMin` (type: `integer`):

Only return instances with at least this much RAM in GB. Note: Azure's Retail Prices API does not expose vCPU/RAM data, so setting this excludes all Azure results — leave empty when comparing both providers.

## `maxResultsPerProvider` (type: `integer`):

Maximum number of price records to return per provider (summed across its regions).

## `trackPriceChanges` (type: `boolean`):

Compares each (provider + region + instance type) price with the previous run via the actor's key-value store, and charges the extra price-change-alert event when the absolute percentage change reaches the threshold.

## `priceChangeThresholdPercentage` (type: `integer`):

Minimum absolute percentage change vs. the previous run to count as a price-change-alert. Only relevant when 'Track price changes' is enabled.

## Actor input object example

```json
{
  "providers": [
    "aws",
    "azure"
  ],
  "awsRegions": [
    "eu-west-1"
  ],
  "azureRegions": [
    "westeurope"
  ],
  "operatingSystem": "Linux",
  "maxResultsPerProvider": 500,
  "trackPriceChanges": false,
  "priceChangeThresholdPercentage": 5
}
```

# Actor output Schema

## `results` (type: `string`):

Alle prijsrecords in het default dataset.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {};

// Run the Actor and wait for it to finish
const run = await client.actor("codeclouds/cloud-compute-prijzen-monitor").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {}

# Run the Actor and wait for it to finish
run = client.actor("codeclouds/cloud-compute-prijzen-monitor").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{}' |
apify call codeclouds/cloud-compute-prijzen-monitor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,codeclouds/cloud-compute-prijzen-monitor"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/Ba4t6gvXQKw9IhmV0/builds/L1DMqcUq6nrYTz01S/openapi.json
