Skip to content
Finitizer

Supported billing export formats

Where to get each billing export, and which columns the analysis uses.

The format is detected from the header row, never from the filename: people rename these files, and the columns are the only reliable signal.

FOCUS 1.x

recommended

AWS, Google Cloud, Azure, and OCI can all emit FOCUS. In AWS it is an export type in Data Exports; in Google Cloud it is a BigQuery billing export view; in Azure it is a Cost Management export.

BilledCost
What was invoiced.
EffectiveCost
Amortized, the one to analyze.
PricingQuantity / PricingUnit
The quantity and unit the rate applies to.
ServiceName / SkuId
What was bought.
ChargeCategory
Usage, Purchase, Tax, Credit, Adjustment.
ChargePeriodStart
When. Drives the day-count normalization.
Tags
Allocation metadata, as a map.

Bring this one if you can. It needs no provider-specific interpretation, which means fewer places for a mapping to be wrong, and it works identically across clouds.

AWS CUR 2.0 (Data Exports)

Billing and Cost Management → Data Exports → Create export → CUR 2.0. Choose CSV (or gzipped CSV) and include resource IDs if you want resource-level drill-down.

line_item_unblended_cost
What was invoiced, and the cost of every ordinary usage line.
savings_plan_savings_plan_effective_cost
Amortized cost of usage a Savings Plan covered.
reservation_effective_cost
Amortized cost of usage a Reserved Instance covered.
line_item_line_item_type
Decides which of the three applies to each line: Usage, DiscountedUsage, SavingsPlanCoveredUsage, fees, Tax, Credit.
line_item_usage_amount / pricing_unit
Quantity and unit.
product_servicecode
The service.
line_item_usage_type / line_item_operation
Together, the SKU.
resource_tags
Tags, as a nested map. The user_ prefix AWS adds to each key is removed.

The amortized cost is built line by line from the line item type, the way Cost Explorer builds its amortized view: covered usage at its effective cost, Savings Plan negation and upfront-fee lines at zero, and unused commitment kept on its fee line. CUR 2.0 has a fixed column set, which is why it is easier to work with than the legacy format. If your export is Parquet, re-export as CSV. Parquet support is not in this version.

AWS CUR (legacy)

The older Cost and Usage Report, still widely deployed. Columns use slash-separated names and the set changes month to month depending on what you used.

lineItem/UnblendedCost
What was charged.
reservation/EffectiveCost / savingsPlan/SavingsPlanEffectiveCost
Amortized, chosen per line item type exactly as for CUR 2.0.
lineItem/UsageAmount
Quantity.
lineItem/ProductCode
The service.
lineItem/UsageType
The SKU.
resourceTags/user:Key
One flattened column per tag key.

The varying column set is the reason a diff across months can find tag columns in one file and not the other. The mapping panel in the tool shows exactly what was matched in each file.

GCP billing export

Billing → Billing export → BigQuery export. Use the detailed export if you want resource-level data. BigQuery cannot export nested or repeated columns (labels, credits) to CSV, so run the query below once per month instead: it flattens one invoice month to exactly the columns the tool reads. Save the result as CSV.

cost
What was charged, after negotiated discounts.
discount_credits
Committed use, sustained use and spending-based discount credits, negative. Netted into cost: they are part of the price.
other_credits
Promotions, free tier and the other credit types, negative. Kept apart, as a reconciling line.
usage_amount_in_pricing_units / usage_pricing_unit
Quantity and unit.
service_description / sku_description
The service and SKU. A SKU whose name starts "Commitment" is a commitment fee, filed with purchases.
project_id
The account dimension.
labels
Resource labels, as JSON.
usage_start_time
The day. Drives the day-count normalization.
currency
The billing account currency. Amounts are shown in it, and two files in different currencies are flagged.
Flattening query, run in BigQuery
-- Finitizer Cloud Bill Diff: one month of the GCP billing export,
-- flattened to the columns the tool reads. Run once per month,
-- changing the invoice month, and save each result as CSV.
-- On the standard (not detailed) export, change resource.name below to
-- CAST(NULL AS STRING): only the detailed export has resource.name, and
-- deleting the line would shift the GROUP BY positions.
-- discount_credits are committed use, sustained use and spending-based
-- discounts, part of the price; other_credits are promotions, free tier
-- and the rest.
SELECT
  TIMESTAMP_TRUNC(usage_start_time, DAY)                       AS usage_start_time,
  service.id                                                   AS service_id,
  service.description                                          AS service_description,
  sku.id                                                       AS sku_id,
  sku.description                                              AS sku_description,
  project.id                                                   AS project_id,
  location.region                                              AS location_region,
  resource.name                                                AS resource_name,
  TO_JSON_STRING(labels)                                       AS labels,
  cost_type,
  currency,
  usage.pricing_unit                                           AS usage_pricing_unit,
  SUM(usage.amount_in_pricing_units)                           AS usage_amount_in_pricing_units,
  SUM(cost)                                                    AS cost,
  SUM(cost_at_list)                                            AS cost_at_list,
  SUM(IFNULL((SELECT SUM(c.amount) FROM UNNEST(credits) AS c WHERE c.type IN ('COMMITTED_USAGE_DISCOUNT', 'COMMITTED_USAGE_DISCOUNT_DOLLAR_BASE', 'SUSTAINED_USAGE_DISCOUNT', 'DISCOUNT', 'FEE_UTILIZATION_OFFSET')), 0)) AS discount_credits,
  SUM(IFNULL((SELECT SUM(c.amount) FROM UNNEST(credits) AS c WHERE IFNULL(c.type, '') NOT IN ('COMMITTED_USAGE_DISCOUNT', 'COMMITTED_USAGE_DISCOUNT_DOLLAR_BASE', 'SUSTAINED_USAGE_DISCOUNT', 'DISCOUNT', 'FEE_UTILIZATION_OFFSET')), 0)) AS other_credits
FROM `my-project.my_dataset.gcp_billing_export_resource_v1_XXXXXX_XXXXXX_XXXXXX`
WHERE invoice.month = '202608'
  -- The table is partitioned by the day each row was loaded. This bound
  -- reads the month and its late rows, not every month in the table.
  AND _PARTITIONTIME >= TIMESTAMP('2026-08-01')
  AND _PARTITIONTIME < TIMESTAMP('2026-09-15')
GROUP BY 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12
ORDER BY 1;

Committed use, sustained use and discount credits are netted into the SKU they discount, so its rate is the one you actually paid and a commitment ending shows as a rate rise. Promotions and free tier are kept apart: with "Include tax, credits, and purchases" ticked they net in too; unticked, they show as a reconciling line. A file from the older query, with one summed credits_amount column, cannot tell the two apart, so all of it is kept apart and the tool says so. The query reads only the partitions that hold the month. A large month may exceed what the console will save as a local CSV; save the result to a table and export that table to Cloud Storage as CSV, which works because every column is now flat.

Not supported yet: Parquet (re-export as CSV), and Azure’s native Cost Management schema (export as FOCUS instead, which Azure supports directly).

Skip the export entirely.

Finitizer connects read-only and keyless to AWS and Google Cloud, normalizes both into one model, and keeps the comparison current without anyone downloading a file.

See how Finitizer works