Skip to content

Reading Bedrock Usage From AWS Cost Explorer

9 min read · updated August 11, 2026

Filtering Cost Explorer to Amazon Bedrock takes one click and gives you a single number. The question people actually have — which model, which token type, which Region, which team — is answered by the usage-type string, which is dense, undocumented in its individual values, and entirely readable once you know its grammar.

The service filter is the easy half

In Cost Explorer, set the date range to at least two full months, group by Service, and filter to Amazon Bedrock. Set granularity to daily rather than monthly: inference spend moves with deployments and traffic, and a monthly bar hides the step change that tells you which day something started.

One subtlety before you trust the total. Bedrock is billed through AWS Marketplace for third-party models, so the Billing entity dimension can split what you think of as one service across two lines. If a Cost Explorer figure disagrees with the Bedrock number on your invoice, check that filter before assuming the data is wrong.

Anatomy of a Bedrock usage type

Now regroup by Usage type with the same Bedrock filter. You will get a list of strings that look like machine identifiers, and they are: Amazon documents the line_item_usage_type field as encoding the Region, the model, the token type, the service tier and whether the request went through cross-region inference. The documented shapes are:

  • {region}-{model}-{token-type} — a standard-tier request on the bedrock-runtime endpoint.
  • {region}-{model}-{token-type}-{tier} — a priority or flex tier request.
  • {region}-{model}-mantle-{token-type}-standard — a bedrock-mantle request.
  • {region}-{model}-{token-type}-cross-region-global — a cross-region request.

Amazon’s own examples make the pattern concrete: USE1-Claude4.6Sonnet-input-tokens is standard-tier input in us-east-1; USE1-Nova2.0Lite-input-tokens-flex is the same thing on the flex tier; USE1-Claude4.6Sonnet-output-tokens-cross-region-global is output that was routed cross-region.

Three things fall out of this immediately. The Region prefix is the AWS billing abbreviation (USE1, USW2, EUW1), not the API Region name, which is why searching for “us-east-1” in this column finds nothing. The model fragment is a marketing-ish short name rather than the API model id, so it will not match the modelId in your code. And the tier suffix means a single model appears under several usage types at once — summing one of them undercounts.

These string formats and examples are Amazon’s, from the Bedrock Cost and Usage Report documentation at the time of writing. The per-model fragments change as models are added and the tier suffixes have grown over time, so treat the grammar as stable and the specific values as something to re-read from Understanding your Amazon Bedrock Cost and Usage Report data.

Four token types, not two

The single most common reconciliation error on this service is assuming there are two token prices. Amazon documents four billed token types, each with its own unit price:

  • Input tokens — usage types matching *-input-tokens.
  • Output tokens*-output-tokens.
  • Cache read tokens *-cache-read-input-token-count, significantly cheaper than input.
  • Cache write tokens *-cache-write-input-token-count, more expensive than input.

AWS is explicit that all four must be accounted for and that summing only input and output will not match the bill — and that this is the most common source of reconciliation gaps, particularly for workloads leaning on prompt caching. The cache-write line is the counterintuitive one: it is a premium you pay on first use of a cached prefix, recovered on subsequent hits. A workload with a low hit rate can be more expensive with caching on than off, and this is the only place in the billing data where you can see that happening.

A second limit is worth knowing before you go looking for it. Amazon states that neither classic CUR nor CUR 2.0 carries a per-request identifier; both aggregate by usage type, operation and resource over an hour or a day. There is no way to attribute a dollar figure to a single prompt from billing data. If you need that, it comes from model invocation logs joined to CUR at the model and usage-type grain, which is the same shape of problem cost attribution describes generally.

Splitting by team

Cost Explorer can group by tag, and Bedrock inference carries tags through several routes, which Amazon lists as: IAM principal tags, session tags passed at role assumption, Bedrock Project tags, and application inference profile tags. In CUR they appear as columns prefixed resourceTags/ and iamPrincipal/ — a tag with key Team becomes resourceTags/Team.

Which route to use is mostly a question of how many profiles you are willing to own. An application inference profile is tied to one model, so a team times a model times a tag set is one profile each, and Amazon itself flags the resulting proliferation as a scaling concern — recommending Projects, or IAM principal attribution where you want per-identity cost without new resources. All three require the same activation step in the Billing console, and all three carry the same 24-hour delay and the same non-retroactive behaviour described in the budget alert page.

Getting the same numbers from the API

Console filters do not survive into a dashboard. The same query through GetCostAndUsage:

aws ce get-cost-and-usage \
  --time-period Start=2026-07-01,End=2026-08-01 \
  --granularity DAILY \
  --metrics UnblendedCost UsageQuantity \
  --filter '{"Dimensions":{"Key":"SERVICE","Values":["Amazon Bedrock"]}}' \
  --group-by Type=DIMENSION,Key=USAGE_TYPE

Ask for UsageQuantity alongside UnblendedCost. Cost alone cannot distinguish a price change from a volume change, and dividing the two gives you an effective rate per usage type — which is the number that reveals whether last month’s increase was more traffic, a switch to a dearer model, or a shift onto a priority tier. Be aware that Cost Explorer API requests are charged per request (AWS documents a fixed per-request fee for paginated API access), so a dashboard polling it every minute is itself a line item.