AWS Spot Prices

Linux EC2 spot history + on-demand list prices

This service stores spot price-change events (not a fixed 5-minute grid). Each series is one instance type in one availability zone: region/availability_zone/instance_type. It also stores Linux on-demand list prices per region and instance type (from AWS’s public price list) so you can compare spot vs on-demand in the chart tooltip.

Quick start

GET/aws/chart

Interactive chart — see Using the chart below for the full UI tour.

GET/aws/latest/cheapest?instance_type=g5.2xlarge

Cheapest current spot for one instance type across all tracked regions/AZs.

curl -sS "$BASE/aws/latest/cheapest?instance_type=g5.2xlarge"

Using the chart

Open /aws/chart. Each line is one instance type in one availability zone (label looks like g5.2xlarge @ us-east-1a). Filter panels start collapsed — expand the section you need. Filters stack: type groups → family → instance type → region → series (fine-tune).

Type groups (purple)
Quick picks: GPU, K8s low density, K8s high density, etc. One click sets the instance-type filter to every type in that group. Click again to clear.
Instance family (amber)
Quick picks by AWS family prefix: g5, inf2, g4ad, p3, etc. Shows every size in that family (e.g. all g5.* types). Combines with other filters. GPU families are highlighted like the GPU group button.
Applied filters (top of sidebar)
Shows which type and region filters are active (any when a box is empty). Counts how many series are hidden and why — e.g. 87 hidden (45 by instance type · 30 by region · 12 by series checkbox).
Instance type (green)
Check one or more types (e.g. p3.2xlarge) to plot that type in every region and AZ you track. Leave all unchecked for no type limit. All types / Clear set or remove this filter. Each row has a tiny only button to select just that type and clear the rest.
Region (cyan)
Check a region (e.g. us-west-2) to plot every instance type in that region (all AZs). Combine with instance type to narrow further — e.g. only p3.2xlarge lines in us-west-2. Leave all unchecked for no region limit. only works the same as in instance type.
Series — type + AZ (pink)
Lists only lines that match the type and region filters above. Uncheck a row to hide that AZ. All listed / None listed toggle every row in the current list (not the whole dataset). only shows just that one AZ line.
Click a line on the graph
Focus that series: thicker line, colored dots at each spot price point (so you know where to hover), other lines fade. While focused, tooltips appear only on the clicked line — dimmed lines are ignored. Click the same line again to clear focus, or use Reset all filters.
Hover · pan · zoom
With no line focused, hover any line for a tooltip: type, AZ, region, time (UTC), spot $/hr, and on-demand $/hr when available (region-level list price at or before that spot sample). After you click to focus, only that line shows tooltips. Drag to pan, scroll to zoom. On-demand is never drawn as a separate line.
Counts
Under Applied filters: how many lines are on the chart and how many were hidden by each filter. Filter checkbox choices stay in your browser if you reload.
  1. All GPU spot lines: Type groups → GPU, or API GET /aws/latest?group=gpu.
  2. All g5 sizes: Instance family → g5, or API GET /aws/latest?family=g5.
  3. One type only: Instance type → only on p4d.24xlarge (or check the type manually).
  4. One region, all types: Region → only on us-west-2.
  5. Both: Type p3.2xlarge + region us-west-2; series panel to drop one AZ.
  6. Inspect a dip: Click a line (dots appear), hover a point for spot vs on-demand; click again to unfocus.
The chart loads the last 2 days first and draws each series as it streams in, then fetches full history in the background (GET /aws/api/history?since=… then GET /aws/api/history). Filters are ANDed: type ∩ region ∩ series checkboxes.

On-demand list prices

On-demand data is region + instance type only (not per AZ). Source: AWS public price list (pricing.us-east-1.amazonaws.com) — Linux, shared tenancy, standard BoxUsage — no EC2 API or extra IAM permissions.

On-demand rows older than 90 days are pruned automatically. If tooltips show spot only, run the on-demand sync/backfill jobs once after deploy.

Series identity

Series IDs look like:

us-east-1/us-east-1a/g5.2xlarge

In URLs you can use slashes or pipe separators:

/aws/series/us-east-1|us-east-1a|g5.2xlarge/history

Instance type groups

Groups are defined in config.yaml (instance_types_gpu, instance_types_kubernetes_low_density, instance_types_kubernetes_high_density, …). Families are derived from configured types (g5.2xlarge → family g5). GPU types can be extended via SPOT_GPU_INSTANCE_TYPES on the server pod.

GET/aws/groups

instance_type_groups, instance_type_families, gpu_instance_types, group_labels, regions.

curl -sS "$BASE/aws/groups"

Filter with group, family (repeat either for unions within that dimension), gpu_only=true, and/or instance_type — all intersected.

All endpoints

Each response is JSON unless noted. Query params can be repeated where noted.

GET/health

Liveness probe.

curl -sS "$BASE/health"
GET/aws/summary

series_count, updated_at, database — no per-series payload.

curl -sS "$BASE/aws/summary"
GET/aws/

Full snapshot: latest price per series plus instance_types, instance_type_groups, gpu_instance_types, group_labels, updated_at. Each series includes is_gpu.

curl -sS "$BASE/aws/"
GET/aws/chart/config

Alias for /aws/groups (used by the chart UI).

curl -sS "$BASE/aws/chart/config"
GET/aws/latest

Latest prices with server-side filter, sort, and limit.

curl -sS "$BASE/aws/latest?group=gpu&sort=price&order=asc"
curl -sS "$BASE/aws/latest?family=g5&family=inf2"
curl -sS "$BASE/aws/latest?gpu_only=true&region=us-west-2"
curl -sS "$BASE/aws/latest?instance_type=g5.2xlarge&sort=price&order=asc"
GET/aws/latest/cheapest

Cheapest series right now. Provide exactly one of instance_type, group, or family. Optional region, gpu_only.

curl -sS "$BASE/aws/latest/cheapest?instance_type=g5.2xlarge"
curl -sS "$BASE/aws/latest/cheapest?group=gpu&region=us-east-1"
curl -sS "$BASE/aws/latest/cheapest?family=g5"
GET/aws/series

Flat list of series IDs (no prices).

curl -sS "$BASE/aws/series"
GET/aws/series/count

{"count": N} — distinct series in the database.

curl -sS "$BASE/aws/series/count"
GET/aws/series/{series_key}/history

JSON time series for one AZ + instance type. Includes point_count.

Series key: slashes or pipes — us-east-1/us-east-1a/g5.2xlarge

curl -sS "$BASE/aws/series/us-east-1/us-east-1a/g5.2xlarge/history?since=2026-05-01T00:00:00Z"
curl -sS "$BASE/aws/series/us-east-1/us-east-1a/g5.2xlarge/history?limit=100"
GET/aws/series/{series_key}/history/tsv

Tab-separated recorded_at and price_usd_per_hour (same query params as history).

curl -sS "$BASE/aws/series/us-east-1/us-east-1a/g5.2xlarge/history/tsv"
GET/aws/series/{series_key}/csv

OHLC-style CSV download (Open/High/Low/Close = price, Volume = 0) for Fidelity / strawberry-market import.

curl -sS "$BASE/aws/series/us-east-1/us-east-1a/g5.2xlarge/csv" -o g5-us-east-1a.csv
GET/aws/api/history/meta

Per-series point_count, is_gpu, labels — no price arrays. Optional since, group, family, gpu_only, instance_type.

curl -sS "$BASE/aws/api/history/meta?group=gpu"
curl -sS "$BASE/aws/api/history/meta?family=inf2"
curl -sS "$BASE/aws/api/history/meta?since=2026-05-25T00:00:00Z&gpu_only=true"
GET/aws/api/history

Bulk history (chart shape). Optional since, group, family, gpu_only, instance_type. Each series includes parallel arrays timestamps, prices (spot), and on_demand_hover (strings for the chart tooltip, e.g. On-demand: $1.2120/hr, or empty when unknown).

curl -sS "$BASE/aws/api/history?since=2026-05-01T00:00:00Z&group=kubernetes_low_density"
curl -sS "$BASE/aws/api/history?family=g5"
curl -sS "$BASE/aws/api/history?instance_type=g5.2xlarge" | jq '.series[0] | {id, on_demand_hover: .on_demand_hover[0:3]}'
GET/aws/chart

Interactive chart UI (loads 2 days first, then full history; series draw as they stream in).

Base URL: Replace $BASE with your server root. It is TLS only: https://spotplot.fraise.farm/, or https://spot-prices.nandling.internal:8787 on the tailnet.