← Agent Frameworks 🕐 15 min read
Agent Frameworks

FOCUS Standard for AI/LLM Spend — FinOps Foundation (2026)

The FinOps Open Cost and Usage Specification (FOCUS) is the cloud industry's first vendor-neutral billing data standard, governed by the FinOps Foundation.

The FinOps Open Cost and Usage Specification (FOCUS) is the cloud industry’s first vendor-neutral billing data standard, governed by the FinOps Foundation. It normalizes cost and usage records from every major cloud provider into a single schema so that a single SQL query works across AWS, Azure, GCP, and Oracle Cloud without custom ETL per provider. FOCUS 1.0 was ratified in 2024; FOCUS 1.1 followed in November 2024; 1.2 shipped in mid-2025; 1.3 is the current release as of mid-2026.

The standard is relevant to AI/LLM spend because Bedrock, Azure OpenAI, and Vertex AI all generate billing data in their own proprietary formats. FOCUS provides—at least partially—the normalization layer needed to analyze model costs alongside compute and storage in a unified view. The gaps, however, are significant and form the core of this note.


1. FOCUS Specification — Key Columns and Normalization Goals

1.1 What FOCUS Normalizes

Before FOCUS, every cloud provider used different column names, cost definitions, and aggregation granularities. An AWS CUR file uses line_item_unblended_cost; Azure calls the equivalent CostInBillingCurrency; GCP uses cost. FOCUS collapses these into a single vocabulary.

The normalization goals are:

  • Single query, multiple providers. One SELECT SUM(EffectiveCost) GROUP BY ServiceName returns apples-to-apples spend across clouds.
  • Consistent cost semantics. Four cost columns with precise definitions prevent the ambiguity that plagues on-demand vs. reserved vs. amortized comparisons.
  • Interoperable tooling. FinOps platforms can ingest any FOCUS-compliant export without custom parsers.
  • Reduced dataset size. FOCUS consolidation typically reduces billing file size ~30% vs. raw CUR.

1.2 Full Column Inventory (FOCUS 1.2 — 57 columns)

FOCUS 1.2 defines 57 columns across six functional families:

Cost Columns (4)

Column Definition
BilledCost The charge as it appears on your invoice. Includes all discounts, reduced rates, and prepaid amortization.
EffectiveCost Amortized cost after applying all discounts and prepaid purchases. Preferred for trending and anomaly detection.
ContractedCost ContractedUnitPrice × PricingQuantity. Reflects negotiated rates before further amortization.
ListCost ListUnitPrice × PricingQuantity. Public on-demand rate; baseline for discount analysis.

Charge Classification Columns (5)

Column Definition
ChargeCategory Replaces CUR’s line_item_type. Values: Usage, Purchase, Tax, Credit, Adjustment.
ChargeClass Distinguishes Correction rows (retroactive adjustments) from standard charges.
ChargeDescription Human-readable description of the charge.
ChargeFrequency One-Time, Recurring, Usage-Based.
ChargePeriodStart / ChargePeriodEnd The time window this charge covers.

Pricing Columns (9)

Column Definition
PricingCategory Standard, Committed, Dynamic, Other.
PricingQuantity Volume of SKU purchased or used. For tokens: the token count at the rate tier.
PricingUnit Unit of measurement. For Bedrock this resolves to tokens (provider-specific); not standardized.
ListUnitPrice Rack rate per pricing unit.
ContractedUnitPrice Negotiated unit price.
SkuId Provider SKU identifier.
SkuMeter Human-readable SKU label, e.g., Claude Sonnet 4.6 Input Tokens.
SkuPriceId Rate card identifier for the specific price applied.
SkuPriceDetails Map of additional pricing attributes (new in 1.2).

Service / Resource Columns (10)

Column Definition
ServiceName The product name, e.g., Amazon Bedrock.
ServiceCategory Highest-level taxonomy. Bedrock falls under AI and Machine Learning.
ServiceSubcategory New in 1.2. For Bedrock: Foundational Models (provider-assigned).
ResourceId ARN or equivalent unique resource identifier.
ResourceName Human-readable resource name.
ResourceType Resource class, e.g., InferenceProfile.
RegionId Provider region code, e.g., us-east-1.
RegionName Human-readable region name.
AvailabilityZone Sub-region zone; typically null for Bedrock (managed service).
Tags Normalized key-value map of resource tags.

Commitment / Discount Columns (7)

Column Definition
CommitmentDiscountId Identifier of the commitment (e.g., Savings Plan ARN).
CommitmentDiscountName Human-readable commitment name.
CommitmentDiscountType Savings Plan, Reserved, Committed Use, etc.
CommitmentDiscountCategory Usage or Spend.
CommitmentDiscountStatus Used, Unused.
CommitmentDiscountQuantity Amount of commitment applied.
CommitmentDiscountUnit Unit for the commitment quantity.

Billing / Account Columns (12+)

Column Definition
BillingAccountId Payer account. In AWS: management account ID.
BillingAccountName Human-readable account name.
BillingAccountType New in 1.2. Values: Management, Member.
SubAccountId Linked / member account.
SubAccountName Member account name.
SubAccountType New in 1.2.
BillingCurrency ISO 4217 currency code.
BillingPeriodStart / BillingPeriodEnd Calendar billing period.
InvoiceId Invoice reference.
InvoiceIssuer Entity issuing the invoice.
Provider Top-level cloud provider: Amazon Web Services, Microsoft Azure, etc.
Publisher Entity that produced the resource. For Bedrock third-party models: Anthropic, Meta, Mistral, etc.

2. AWS CUR 2.0 → FOCUS Column Mapping for Bedrock

AWS supports native FOCUS exports via AWS Data Exports (CUR 2.0). The mapping below covers the columns most relevant to Bedrock analysis.

2.1 Core Column Mapping

CUR 2.0 Column FOCUS Column Notes for Bedrock
line_item_usage_type SkuMeter Encodes region, model, token direction, tier, and routing. Most information-dense field.
line_item_operation x_Operation (custom) In FOCUS report: values include InvokeModelInference, InvokeModelStreamingInference. Not a standard FOCUS column; AWS surfaces it as an extension column.
line_item_line_item_type ChargeCategory UsageUsage; CreditCredit; TaxTax.
line_item_unblended_cost BilledCost Post-discount invoice cost.
line_item_blended_cost No direct FOCUS equivalent; EffectiveCost is the closest for amortized analysis.
pricing_public_on_demand_cost ListCost Rack-rate cost for this usage.
pricing_unit PricingUnit For Bedrock: varies by usage type (e.g., token, 1000 tokens). Not yet standardized to a universal AI unit.
line_item_usage_amount PricingQuantity Token count for this line item.
product_servicename ServiceName Always Amazon Bedrock for Bedrock.
product_region RegionId AWS region code.
line_item_resource_id ResourceId Inference profile ARN, if using application inference profiles; otherwise null.
line_item_iam_principal No FOCUS equivalent CUR 2.0 only. IAM ARN of caller. Critical for multi-tenant attribution. See Section 7.
resourceTags/{key} Tags/{key} Resource-level tags (Projects, inference profiles).
iamPrincipal/{key} No FOCUS equivalent IAM-principal-derived tags. No FOCUS column exists for caller identity.

2.2 Bedrock Usage Type Anatomy

The line_item_usage_type / SkuMeter field encodes five dimensions in a single string:

{region}-{model-id}-{token-type}[-{tier}][-cross-region-global]

Examples and decoded structure:

Usage Type Model Token Type Tier Routing
USE1-Claude4.6Sonnet-input-tokens Claude Sonnet 4.6 Input Standard In-region
USE1-Claude4.6Sonnet-output-tokens Claude Sonnet 4.6 Output Standard In-region
USE1-Claude4.6Sonnet-cache-read-input-token-count Claude Sonnet 4.6 Cache Read Standard In-region
USE1-Claude4.6Sonnet-cache-write-input-token-count Claude Sonnet 4.6 Cache Write Standard In-region
USE1-Claude4.6Sonnet-output-tokens-cross-region-global Claude Sonnet 4.6 Output Standard Cross-region
USE1-Nova2.0Lite-input-tokens-flex Amazon Nova 2 Lite Input Flex In-region
USE1-openai.gpt-oss-120b-mantle-input-tokens-standard OpenAI GPT-OSS-120B Input Standard In-region (Bedrock Mantle)

Reconciliation note: All four token types — input, output, cache read, cache write — generate separate CUR line items with different unit prices. A query summing only input + output tokens will undercount total spend. This is the most common reconciliation gap in Bedrock cost analysis.

2.3 ChargeCategory Values for Bedrock

For Bedrock, the ChargeCategory column is almost always Usage. Exceptions:

  • Credit — Bedrock promotional credits or enterprise credit memos
  • Tax — applicable where AWS charges VAT/GST
  • Adjustment — retroactive corrections (e.g., billing error remediation)

There is no Purchase row for Bedrock on-demand; Provisioned Throughput commitments generate a Purchase row at purchase time and Usage rows at consumption time.


3. FOCUS-Compliant Cost Tools for AI Spend

3.1 Apptio Cloudability (IBM)

IBM acquired both Cloudability (via Apptio) and Kubecost, creating the dominant enterprise FinOps stack. Cloudability ingests FOCUS-format exports natively from AWS Data Exports, Azure Cost Management, and GCP Billing. Its AI spend features as of 2026:

  • Dashboards for Bedrock, Azure OpenAI, and Vertex AI line items grouped by model
  • Showback/chargeback rules that allocate AI spend by cost center or team using tag mappings
  • FOCUS Tags column surfaced as allocation dimensions in the UI
  • No native token-unit display; tokens appear in the PricingQuantity column but are rendered as raw numbers without model-aware context

Gap: Cloudability’s anomaly detection thresholds are calibrated for compute (hourly patterns). Token-based workloads have different temporal patterns (bursty, request-driven) that generate false positives.

3.2 CloudZero

CloudZero positions itself on unit economics — cost per customer, cost per feature — rather than raw spend dashboards. Its architecture captures spend at the code level by instrumenting API calls and correlating them to business dimensions.

  • FOCUS ingest supported for AWS and Azure
  • Bedrock costs can be mapped to feature/customer dimensions via CloudZero’s CostFormation rules
  • Token volumes from Bedrock logs can be joined to CUR via model + time window, producing cost-per-token-per-feature metrics
  • No first-class FOCUS export; CloudZero’s own data model is the canonical representation internally

3.3 Kubecost / OpenCost

Kubecost 3.0 (IBM) focuses on Kubernetes GPU and CPU cost allocation, with NVIDIA DCGM exporter integration for GPU utilization tracking. Relevant for self-hosted LLM inference (vLLM, TGI on EKS), not for managed API services like Bedrock.

OpenCost is the CNCF open-source project underlying Kubecost. It uses the FOCUS PricingUnit and ConsumedQuantity columns to represent GPU/CPU utilization but has no token-specific dimensions.

Use case split:

  • Bedrock / managed API → Cloudability or CloudZero
  • Self-hosted inference on Kubernetes → Kubecost/OpenCost

3.4 Finout

Finout is notable for its FOCUS-native data model — it stores all ingested billing data in FOCUS format internally, making cross-cloud queries first-class. Its “MegaBill” view merges Bedrock, Azure OpenAI, and GCP Vertex AI line items in a single FOCUS-normalized table. As of 2026, Finout added a dedicated AI spend module with model-level grouping using SkuMeter parsing.

3.5 nOps / Vantage

Both platforms support FOCUS ingest. Neither has AI-specific token-unit features as of mid-2026. They surface Bedrock as a standard ServiceName = 'Amazon Bedrock' filter with SkuMeter-based drill-down.


4. FinOps Foundation AI/ML Working Group

4.1 Scope and Outputs

The FinOps Foundation formalized the FinOps for AI practice area in 2025, with a working group that now has representation from AWS, Microsoft, Google, Anthropic, and major FinOps tool vendors. The 2026 State of FinOps survey found 98% of respondents managing AI spend — up from 31% two years prior — making AI cost governance the top forward-looking priority.

Working group outputs to date:

  1. FinOps for AI Framework Guidance — extends the core FinOps lifecycle (Inform → Optimize → Operate) with AI-specific stages: Model Selection, Context Optimization, Caching Strategy, and Agentic Cost Control.

  2. Recommended Tagging Taxonomy — a standardized tag key set for AI workloads (see Section 8).

  3. Unit Economics Definitions — cost-per-token, cost-per-request, cost-per-resolved-task as the canonical AI FinOps metrics, replacing raw monthly spend.

  4. FOCUS Gap Register — a documented list of AI-specific gaps in FOCUS 1.x submitted to the FOCUS steering committee for 1.4/1.5 consideration (see Section 6).

  5. Agentic Cost Control Guidance — recommendations for capping agent loop steps, alerting on per-task cost overruns, and failing CI/CD builds when cost-per-request budgets are exceeded.

4.2 LLM Cost Attribution Model

The working group’s attribution model identifies four levels of granularity:

Level Attribution Grain Tool
L1 Cloud account / subscription CUR + cost allocation tags
L2 Team / cost center IAM principal tags + project tags
L3 Feature / application Application inference profiles + custom tags
L4 Request / prompt Model invocation logs (not CUR; CUR does not carry request IDs)

L4 attribution requires joining CUR data to model invocation logs at the model + time-window grain. CUR does not carry per-request identifiers; fine-grained prompt-level cost must be reconstructed from logs.


5. How FOCUS Handles Token-Based Pricing

Token-based pricing is structurally different from the compute and storage pricing FOCUS was designed for:

Pricing Dimension Compute (EC2) Object Storage (S3) LLM Tokens (Bedrock)
Unit vCPU-hour GB-month 1,000 tokens
Direction N/A N/A Input / Output / Cache Read / Cache Write
Model dimension Instance type Storage class Model ID (10s of variants)
Pricing variability Flat / savings plan Flat Varies by model, tier, direction, routing

FOCUS accommodates token pricing through existing general-purpose columns:

  • PricingUnit: Holds the provider-specified unit string. For Bedrock, AWS uses 1K tokens or tokens depending on the model. This is not standardized across providers — Azure OpenAI uses 1,000 tokens, GCP Vertex uses characters for some models.
  • PricingQuantity: Holds the token count (or token-count divided by 1,000, depending on the usage type). The denominator is encoded in PricingUnit and must be parsed.
  • SkuMeter: The most information-rich field for AI workloads. Contains model ID, token direction, tier, and routing — all encoded in a single string with no machine-readable sub-fields.
  • Publisher: Distinguishes Anthropic-model charges from Amazon-model charges within Bedrock, enabling cross-provider model family analysis.

The PricingCategory = Usage-Based applies correctly to token pricing. ChargeFrequency = Usage-Based is accurate.

For Azure OpenAI, the FinOps Toolkit normalizes FOCUS data and publishes derived TokensConsumed and CostPerToken calculated columns on top of the standard FOCUS export — but these are non-standard extensions, not part of the FOCUS specification.


6. Gaps in FOCUS 1.0–1.3 for AI Workloads

6.1 Confirmed Gaps (as of FOCUS 1.3)

Gap Impact Workaround
No ModelId column Cannot filter or group by model without string-parsing SkuMeter Parse SkuMeter with regex in SQL; add computed column
No TokenDirection column Input vs. output vs. cache costs require SkuMeter parsing Parse usage type pattern
No TokenCount column Token volumes buried in PricingQuantity with inconsistent denominators Normalize via PricingUnit
No standardized PricingUnit for tokens 1K tokens, tokens, characters all appear; cross-provider comparison requires manual mapping Maintain a provider-unit mapping table
No ModelFamily or ModelVersion dimension Claude 3 Haiku vs. Claude Sonnet 4.6 are indistinguishable without parsing Maintain a model taxonomy lookup
No ServiceTier column Standard vs. Priority vs. Flex tier affects unit price; tier is embedded in usage type Parse usage type
No RoutingType column Cross-region inference priced differently; routing embedded in usage type Parse usage type
No caller identity column line_item_iam_principal exists in CUR 2.0 but has no FOCUS equivalent Use CUR 2.0 format instead of FOCUS format, or join FOCUS to CUR on row key
SkuMeter not machine-parseable All model metadata is a freeform string with no schema Regex + lookup table
No PromptCacheId dimension Cache read/write tokens cannot be linked to the cache entry that produced them Model invocation logs only

6.2 FOCUS Steering Committee Roadmap

FOCUS 1.4/1.5 (expected late 2026 / early 2027) is anticipated to address:

  • Structured SKU metadata columns (replacing freeform SkuMeter for AI models)
  • Token-specific pricing units standardization
  • Caller/principal identity (likely as an optional extension column)
  • Reasoning token support (separate pricing for chain-of-thought tokens, now offered by Anthropic and OpenAI)

Until those columns ship, every production Bedrock cost analysis requires parsing line_item_usage_type or SkuMeter with provider-specific regex patterns.


7. Building a FOCUS-Normalized Bedrock View in Athena

7.1 Prerequisites

  • AWS Data Exports enabled with CUR 2.0 format (not legacy CUR)
  • An Athena database and crawler configured against the S3 export bucket
  • Cost allocation tags activated in AWS Billing console (24-hour propagation lag after activation)
  • For IAM principal attribution: CUR 2.0 format required; FOCUS export format does not carry line_item_iam_principal

7.2 CUR 2.0 Table Schema (Relevant Columns)

The Athena table created by the CUR 2.0 crawler exposes these columns for Bedrock analysis:

-- Key columns in the CUR 2.0 Athena table
line_item_usage_type          VARCHAR   -- encodes model, token type, tier, routing
line_item_operation           VARCHAR   -- InvokeModelInference | InvokeModelStreamingInference
line_item_unblended_cost      DOUBLE    -- BilledCost equivalent
line_item_usage_amount        DOUBLE    -- token count (raw; denominator in pricing_unit)
pricing_unit                  VARCHAR   -- e.g. "tokens", "1K tokens"
pricing_public_on_demand_cost DOUBLE    -- ListCost equivalent
line_item_iam_principal       VARCHAR   -- IAM ARN of caller (CUR 2.0 only)
product_servicename           VARCHAR   -- "Amazon Bedrock"
product_region                VARCHAR   -- AWS region
line_item_line_item_type      VARCHAR   -- Usage | Credit | Tax | Adjustment
resource_tags                 MAP       -- resourceTags/* columns
iam_principal_tags            MAP       -- iamPrincipal/* columns
line_item_usage_start_date    TIMESTAMP
line_item_usage_end_date      TIMESTAMP

7.3 Model Extraction UDF (Athena / Presto)

Extract model ID, token direction, and tier from the usage type string:

-- Athena SQL: Parse Bedrock usage type into structured dimensions
-- Table: your_cur_database.cur_data
-- Adjust the regex patterns to match your active models

WITH bedrock_raw AS (
  SELECT
    line_item_usage_start_date                          AS charge_period_start,
    product_region                                      AS region_id,
    line_item_usage_type                                AS sku_meter,
    line_item_operation                                 AS operation,
    line_item_iam_principal                             AS caller_arn,
    line_item_unblended_cost                            AS billed_cost,
    pricing_public_on_demand_cost                       AS list_cost,
    line_item_usage_amount                              AS pricing_quantity,
    pricing_unit                                        AS pricing_unit_raw,

    -- Normalize token count to raw tokens
    CASE
      WHEN lower(pricing_unit) LIKE '%1k%'
        OR lower(pricing_unit) LIKE '%1,000%' THEN line_item_usage_amount * 1000
      ELSE line_item_usage_amount
    END                                                 AS token_count,

    -- Extract model ID from usage type
    -- Pattern: {region_prefix}-{model_id}-{token_type}[-{tier}][-cross-region-global]
    regexp_extract(
      line_item_usage_type,
      '^[A-Z0-9]+-(.+?)-(input-tokens|output-tokens|cache-read-input-token-count|cache-write-input-token-count)',
      1
    )                                                   AS model_id,

    -- Extract token direction
    CASE
      WHEN line_item_usage_type LIKE '%-cache-read-input-token-count%'  THEN 'cache_read'
      WHEN line_item_usage_type LIKE '%-cache-write-input-token-count%' THEN 'cache_write'
      WHEN line_item_usage_type LIKE '%-output-tokens%'                 THEN 'output'
      WHEN line_item_usage_type LIKE '%-input-tokens%'                  THEN 'input'
      ELSE 'unknown'
    END                                                 AS token_direction,

    -- Extract service tier
    CASE
      WHEN line_item_usage_type LIKE '%-priority%' THEN 'priority'
      WHEN line_item_usage_type LIKE '%-flex%'     THEN 'flex'
      ELSE 'standard'
    END                                                 AS service_tier,

    -- Detect cross-region routing
    CASE
      WHEN line_item_usage_type LIKE '%-cross-region-global%' THEN true
      ELSE false
    END                                                 AS is_cross_region

  FROM your_cur_database.cur_data
  WHERE product_servicename = 'Amazon Bedrock'
    AND line_item_line_item_type = 'Usage'
    AND year = '2026'         -- partition filter; adjust for your partition scheme
)
SELECT *
FROM bedrock_raw;

7.4 FOCUS-Normalized View

This view maps CUR 2.0 columns to their FOCUS equivalents and adds parsed AI dimensions:

-- Create a FOCUS-normalized view with AI extensions
CREATE OR REPLACE VIEW focus_bedrock_v1 AS
WITH parsed AS (
  SELECT
    -- FOCUS standard columns
    'Amazon Web Services'                               AS provider,
    'Amazon Bedrock'                                    AS service_name,
    'AI and Machine Learning'                           AS service_category,
    'Foundational Models'                               AS service_subcategory,
    'Usage'                                             AS charge_category,
    'Usage-Based'                                       AS charge_frequency,
    product_region                                      AS region_id,
    line_item_usage_start_date                          AS charge_period_start,
    line_item_usage_end_date                            AS charge_period_end,
    line_item_unblended_cost                            AS billed_cost,
    pricing_public_on_demand_cost                       AS list_cost,
    line_item_usage_amount                              AS pricing_quantity,
    pricing_unit                                        AS pricing_unit,
    line_item_usage_type                                AS sku_meter,
    line_item_resource_id                               AS resource_id,

    -- Publisher derived from model prefix
    CASE
      WHEN lower(line_item_usage_type) LIKE '%-claude%'     THEN 'Anthropic'
      WHEN lower(line_item_usage_type) LIKE '%-llama%'      THEN 'Meta'
      WHEN lower(line_item_usage_type) LIKE '%-nova%'       THEN 'Amazon'
      WHEN lower(line_item_usage_type) LIKE '%-mistral%'    THEN 'Mistral AI'
      WHEN lower(line_item_usage_type) LIKE '%-openai%'
        OR lower(line_item_usage_type) LIKE '%-gpt%'        THEN 'OpenAI'
      WHEN lower(line_item_usage_type) LIKE '%-titan%'      THEN 'Amazon'
      ELSE 'Unknown'
    END                                                 AS publisher,

    -- Non-standard AI extension columns (x_ prefix per FOCUS convention)
    regexp_extract(
      line_item_usage_type,
      '^[A-Z0-9]+-(.+?)-(input-tokens|output-tokens|cache-read-input-token-count|cache-write-input-token-count)',
      1
    )                                                   AS x_model_id,

    CASE
      WHEN line_item_usage_type LIKE '%-cache-read-input-token-count%'  THEN 'cache_read'
      WHEN line_item_usage_type LIKE '%-cache-write-input-token-count%' THEN 'cache_write'
      WHEN line_item_usage_type LIKE '%-output-tokens%'                 THEN 'output'
      WHEN line_item_usage_type LIKE '%-input-tokens%'                  THEN 'input'
      ELSE 'unknown'
    END                                                 AS x_token_direction,

    CASE
      WHEN line_item_usage_type LIKE '%-priority%' THEN 'priority'
      WHEN line_item_usage_type LIKE '%-flex%'     THEN 'flex'
      ELSE 'standard'
    END                                                 AS x_service_tier,

    CASE
      WHEN line_item_usage_type LIKE '%-cross-region-global%' THEN true
      ELSE false
    END                                                 AS x_is_cross_region,

    -- Normalize token count to raw tokens regardless of pricing_unit denominator
    CASE
      WHEN lower(pricing_unit) LIKE '%1k%'
        OR lower(pricing_unit) LIKE '%1,000%' THEN line_item_usage_amount * 1000
      ELSE line_item_usage_amount
    END                                                 AS x_token_count,

    -- Caller identity (CUR 2.0 only; no FOCUS equivalent)
    line_item_iam_principal                             AS x_caller_arn,
    split_part(line_item_iam_principal, '/', -1)        AS x_caller_session_name

  FROM your_cur_database.cur_data
  WHERE product_servicename = 'Amazon Bedrock'
    AND line_item_line_item_type = 'Usage'
)
SELECT * FROM parsed;

7.5 Analytical Queries Against the View

Cost by model and token direction, current month:

SELECT
  x_model_id,
  x_token_direction,
  x_service_tier,
  SUM(billed_cost)    AS total_billed_cost,
  SUM(x_token_count)  AS total_tokens,
  ROUND(
    SUM(billed_cost) / NULLIF(SUM(x_token_count), 0) * 1000000,
    6
  )                   AS cost_per_million_tokens
FROM focus_bedrock_v1
WHERE charge_period_start >= DATE_TRUNC('month', CURRENT_DATE)
GROUP BY x_model_id, x_token_direction, x_service_tier
ORDER BY total_billed_cost DESC;

Cost by IAM caller (team attribution):

SELECT
  x_caller_arn,
  x_model_id,
  SUM(billed_cost)    AS total_billed_cost,
  SUM(x_token_count)  AS total_tokens
FROM focus_bedrock_v1
WHERE charge_period_start >= DATE_ADD('day', -30, CURRENT_DATE)
GROUP BY x_caller_arn, x_model_id
ORDER BY total_billed_cost DESC
LIMIT 50;

Cache efficiency analysis (cache read savings):

SELECT
  x_model_id,
  SUM(CASE WHEN x_token_direction = 'input'      THEN billed_cost ELSE 0 END) AS input_cost,
  SUM(CASE WHEN x_token_direction = 'output'     THEN billed_cost ELSE 0 END) AS output_cost,
  SUM(CASE WHEN x_token_direction = 'cache_read' THEN billed_cost ELSE 0 END) AS cache_read_cost,
  SUM(CASE WHEN x_token_direction = 'cache_write'THEN billed_cost ELSE 0 END) AS cache_write_cost,
  SUM(billed_cost)                                                             AS total_cost,
  SUM(CASE WHEN x_token_direction IN ('cache_read','cache_write') THEN x_token_count ELSE 0 END)
    / NULLIF(SUM(x_token_count), 0) * 100                                      AS cache_token_pct
FROM focus_bedrock_v1
WHERE charge_period_start >= DATE_ADD('day', -30, CURRENT_DATE)
GROUP BY x_model_id
ORDER BY total_cost DESC;

Cross-region cost premium:

SELECT
  x_model_id,
  x_is_cross_region,
  SUM(x_token_count)  AS tokens,
  SUM(billed_cost)    AS cost,
  ROUND(
    SUM(billed_cost) / NULLIF(SUM(x_token_count), 0) * 1000000,
    6
  )                   AS cost_per_million_tokens
FROM focus_bedrock_v1
WHERE charge_period_start >= DATE_ADD('day', -30, CURRENT_DATE)
GROUP BY x_model_id, x_is_cross_region
ORDER BY x_model_id, x_is_cross_region;

8. Cost Allocation Tag Standards — FinOps Foundation Recommendations for AI Workloads

The FinOps for AI working group recommends a five-dimension tagging structure applied at both the IAM principal level and the application inference profile level:

Tag Key Example Values Attribution Level
Environment production, staging, development L2
Team data-science, product-ml, platform-eng L2
CostCenter cc-1234, product-ai, marketing-ai L2
Project rag-pipeline-v2, customer-support-bot L3
WorkloadType inference, batch-inference, fine-tuning, embedding L3
Application search-reranker, doc-summarizer L3
ModelFamily claude, nova, llama L3 (supplemental)

8.2 AWS-Specific Implementation

AWS exposes tag-based attribution through three mechanisms, each with distinct CUR representation:

Mechanism 1: IAM Principal Tags

Attach tags directly to IAM users or roles. Tags flow through to CUR as iamPrincipal/{key} columns.

# Tag an IAM role used for Bedrock inference
aws iam tag-role \
  --role-name bedrock-inference-role \
  --tags Key=Team,Value=data-science \
         Key=CostCenter,Value=cc-1234 \
         Key=Project,Value=rag-pipeline-v2

Mechanism 2: Bedrock Projects

Group inference resources under a Bedrock Project. Project tags appear as resourceTags/{key} in CUR. Projects are the recommended mechanism for L3 (feature/application) attribution.

aws bedrock create-project \
  --project-name "customer-support-bot" \
  --tags Team=product-ml,Environment=production,WorkloadType=inference

Mechanism 3: Application Inference Profiles

Create named inference profiles that wrap a model with a fixed set of tags. All requests routed through the profile inherit the profile’s tags. This is the cleanest mechanism for multi-tenant gateway architectures where the gateway calls Bedrock on behalf of multiple downstream applications.

aws bedrock create-application-inference-profile \
  --inference-profile-name "rag-pipeline-prod" \
  --model-source '{"copyFrom": "arn:aws:bedrock:us-east-1::foundation-model/anthropic.claude-sonnet-4-6-v1:0"}' \
  --tags Application=rag-pipeline,Team=data-science,Environment=production

8.3 Tag Activation Requirement

Tags must be explicitly activated as cost allocation tags in the AWS Billing console before they appear in CUR or Cost Explorer. Propagation takes 24–48 hours after activation. This is a common operational gap: teams instrument their code correctly but forget to activate tags in Billing, resulting in silent data loss from the CUR perspective.

The FinOps Foundation working group recommends four governance controls for AI tagging:

  1. Tag policy enforcement. AWS Organizations tag policies can require specific keys on IAM roles used for Bedrock. A role without Team and CostCenter tags should fail a pre-deployment policy check.

  2. Tag coverage dashboards. Track what percentage of Bedrock BilledCost has a populated Team tag vs. falls into an Untagged bucket. Target: ≥95% tagged within 90 days of program launch.

  3. Gateway-enforced tagging. For LLM gateway architectures (LiteLLM, custom routers), the gateway layer should assume a per-application IAM role (with AssumeRole) that carries the correct tags. This prevents individual service teams from needing IAM knowledge to tag correctly.

  4. CI/CD validation. Bedrock deployment pipelines should validate that the inference profile or IAM role being deployed carries all required tag keys before the deployment is approved.


9. Limitations and Known Issues

CUR does not carry per-request identifiers. CUR aggregates charges by usage type, operation, and pricing/resource over an hour or a day. To attribute cost to a specific prompt or conversation, you must use Bedrock model invocation logs and join them to CUR at the model + time-window grain. This join is approximate, not exact.

FOCUS format vs. CUR 2.0 format tradeoff. AWS Data Exports can produce either FOCUS-format output or CUR 2.0 format output. FOCUS format omits line_item_iam_principal — the single most useful column for multi-tenant attribution. Teams that need caller identity attribution should use CUR 2.0 format and map to FOCUS columns manually (as in the view above) rather than using the native FOCUS export.

Regex fragility. The SkuMeter / line_item_usage_type parsing patterns in this note are based on the current AWS naming convention. AWS has historically changed model ID string formatting (e.g., anthropic.claude-3-haikuClaude4.6Haiku) when releasing new model generations. Regex patterns require maintenance with each major model family update.

Prompt cache accounting. Cache write tokens are priced higher than standard input tokens; cache read tokens are priced lower. Workloads with large system prompts can see cache write costs that exceed inference costs in the first request of each context window. This is counterintuitive and frequently miscategorized in dashboards that only show “input” and “output” buckets.

Commitment discount representation. Bedrock Provisioned Throughput generates a Purchase ChargeCategory row at commitment time and Usage rows as it is consumed. FOCUS handles this correctly via CommitmentDiscountStatus (Used / Unused), but tools must explicitly handle the Bedrock Provisioned Throughput Purchase row to avoid double-counting spend.


10. Summary: What FOCUS Does and Does Not Solve for AI Spend

Concern FOCUS Solves? Note
Multi-cloud cost in one schema Yes AWS, Azure, GCP, Oracle all support FOCUS export
Bedrock vs. Azure OpenAI comparison Partial ServiceName and Publisher work; SkuMeter formats differ and require parsing
Cost by model family No (native) Requires SkuMeter parsing; no ModelId column
Input vs. output token split No (native) Requires usage type parsing
Cache read/write cost tracking No (native) Requires usage type parsing
Cross-region pricing visibility No (native) Requires usage type parsing
IAM caller attribution No Not in FOCUS spec; use CUR 2.0 format
Commitment discount handling Yes CommitmentDiscountStatus covers Provisioned Throughput
Chargeback / showback Partial Tags column works; activation and governance required
Reasoning token pricing No Not in FOCUS 1.3; expected in 1.4/1.5

The practical conclusion: FOCUS is a necessary normalization layer but not a sufficient one for AI cost governance. Production Bedrock deployments require a supplemental parsing layer — either a SQL view of the type documented in Section 7, or a FinOps tool with native model-awareness — to expose the dimensions that FOCUS 1.3 does not yet standardize.


Sources: FinOps Foundation FOCUS specification v1.1/v1.2 (focus.finops.org); AWS Bedrock CUR documentation (docs.aws.amazon.com/bedrock); AWS Cloud Financial Management blog — IAM principal tracking post (2026); AWS Data Exports granular Bedrock visibility announcement (January 2026); FinOps for AI working group overview (finops.org/wg/finops-for-ai-overview); State of FinOps 2026 survey (data.finops.org); IAN Cloud FOCUS 1.3 analysis (iancloud.ai); Rick Pollick — LLM cost governance (rickpollick.com); Microsoft Community Hub — Azure OpenAI FOCUS unit economics (techcommunity.microsoft.com); Amnic FOCUS 2026 guide (amnic.com).