Cloud cost

Embed
Preview of the card
<a href="https://forumulate.com/p/watchtower/docs/cost"><img src="https://forumulate.com/api/public/orgs/watchtower/spaces/docs/pages/ba115530-e7f3-4271-ba35-ed0b47435e7c/social-card.svg?v=3e7ae33eec8b" alt="Cloud cost" width="600" height="315"></a>

Watchtower shows cloud spend next to telemetry: cost per service, team, provider, region or tag, week over week movers, cost anomalies and savings candidates. It is deliberately minimal; for budgets, commitments and chargeback use a dedicated FinOps tool (for example the FinOps Foundation's FOCUS-compatible tools, Vantage, Infracost or your cloud's own console).

Getting data in

  • Billing export bucket. POST /v1/projects/{p}/cost-sources with kind (focus, aws_cur, azure_export, gcp_export), bucket, prefix and credentials (sealed, never returned) or a credentials_ref. The archiver lists the prefix hourly (or daily), reads new .csv / .csv.gz files and maps them to FOCUS columns. A file is ingested again only when its etag changes; the insert token is the file key plus etag, so delivery is at-least-once with best-effort deduplication.

  • Upload. POST /v1/projects/{p}/cost-sources/upload?kind=focus with a CSV body (at most 100 MiB).

  • Custom costs (SaaS, AI spend) are FOCUS rows with their own ProviderName.

  • Parquet exports are not read yet; export CSV.

AWS CUR columns used: lineItem/UnblendedCost, lineItem/UsageStartDate, lineItem/ResourceId, product/ProductName, product/instanceType, product/region, lineItem/UsageAccountId, lineItem/UsageAmount and resourceTags/user:* (tags).

Allocation

PUT /v1/projects/{p}/cost/rules replaces an ordered list; the first rule whose match pairs all hold (tag:<key>, account, resource_id, resource_prefix, service_name, provider, region) sets the service and team. A line no rule matches is unallocated, except that a service tag names the service. Rules apply to lines ingested after the change.

Reads

  • GET /v1/projects/{p}/cost?group_by=service|team|provider|region|tag:<key>&from&to (daily; 15 months retained) with totals, unallocated and movers (last 7 days against the 7 before).

  • GET /v1/projects/{p}/cost/recommendations: idle resources (CPU p95 under 5% for 14 days), unattached volumes (cost with no usage in 30 days) and oversized instances (CPU and memory p95 under 30%, suggests the next smaller size of the family; saving is half the cost). Utilization comes from system.cpu.utilization and system.memory.utilization series labelled with cloud.resource_id or host.id equal to the cost line's resource id. Savings are estimates from the last 30 days of cost.

Alerting

Create an alert rule of kind cost_anomaly ({"cost_anomaly": {"sensitivity": 50}}, condition gt 0.5). Each service with at least 30 days of cost history is scored on its newest complete day against the 35 days before it.

Updated