AWS CUR 2.0 and Athena: FinOps Queries That Replace Spreadsheet Exports (2026)
Quick summary: CUR 2.0 (generally available 2024, default for new exports in 2025) adds line-item resource IDs and Savings Plan attribution columns Athena needs for serious chargeback. A standard FinOps query pack answers top-10 services, untagged spend, and SP coverage in under 60 seconds.
Key Takeaways
- CUR 2
- 0 (generally available 2024, default for new exports in 2025) adds line-item resource IDs and Savings Plan attribution columns Athena needs for serious chargeback
- A standard FinOps query pack answers top-10 services, untagged spend, and SP coverage in under 60 seconds
- June 2026: Most enterprise AWS accounts we audit have CUR 2
- 0 enabled to S3 with Athena integration — but engineers still screenshot Cost Explorer because nobody owns the SQL
Table of Contents
June 2026: Most enterprise AWS accounts we audit have CUR 2.0 enabled to S3 with Athena integration — but engineers still screenshot Cost Explorer because nobody owns the SQL. CUR 2.0 is the only first-party source that ties resource IDs, tags, and commitment attribution on the same row for ad-hoc FinOps.
Engagement shape
Healthcare platform, 14 linked accounts, ~$190k/mo, chargeback to internal LOBs. Before CUR SQL: finance exported CE CSVs weekly (~6 hours analyst time). After CUR 2.0 + Athena views: automated daily LOB rollups, untagged spend alert when >8% of daily total. Analyst time dropped to ~45 min/week for exceptions only.
Setup checklist (Monday morning)
- Billing console → Data exports → create CUR 2.0 → Parquet → S3 bucket with lifecycle to Glacier after 13 months.
- Enable Athena integration (creates crawler + table).
- Create database
aws_curand viewcur_dailynormalizingline_item_usage_start_date. - Partition by
year,month— mandatory for query cost control. - Grant FinOps role
Athena+Glueread on bucket; deny public ACLs on CUR bucket.
Three queries we run on every new account
Top 10 services (last 30 days):
SELECT line_item_product_code AS service,
ROUND(SUM(line_item_unblended_cost), 2) AS cost_usd
FROM cur_daily
WHERE line_item_usage_start_date >= date_add('day', -30, current_date)
GROUP BY 1
ORDER BY 2 DESC
LIMIT 10;
Untagged spend (% of total):
SELECT ROUND(100.0 * SUM(CASE WHEN resource_tags_user_cost_center = '' THEN line_item_unblended_cost ELSE 0 END)
/ SUM(line_item_unblended_cost), 2) AS untagged_pct
FROM cur_daily
WHERE line_item_usage_start_date >= date_add('day', -7, current_date);
Savings Plan coverage gap (simplified):
SELECT DATE(line_item_usage_start_date) AS day,
ROUND(SUM(savings_plan_total_commitment_to_date), 2) AS sp_commit,
ROUND(SUM(line_item_unblended_cost), 2) AS on_demand_equiv
FROM cur_daily
WHERE line_item_usage_start_date >= date_add('day', -30, current_date)
GROUP BY 1
ORDER BY 1;
(Column names vary slightly by export version — validate against your table DDL in Glue.)
Honest gaps
- CUR lags 8–24 hours — not for real-time throttling.
- Marketplace line items need separate joins.
- Bedrock token-level attribution may need service-specific dashboards in addition to CUR.
Next steps
- Pillar: FinOps on AWS complete guide
- Model commitment gaps: Savings Plans calculator
- Cost optimization hub
If you only do one thing this week
Run the top 10 services query and compare to Cost Explorer’s service view for the same window. If totals diverge >2%, fix partition filters before building chargeback on bad data.
AWS Cloud Architect & AI Expert
AWS-certified cloud architect and AI expert with deep expertise in cloud migrations, cost optimization, and generative AI on AWS.