AWS Builder Center
Amazon Bedrock Cost Attribution: A Prescriptive Guide

Amazon Bedrock Cost Attribution: A Prescriptive Guide

Picking the right mix of cost tracking approaches is often the hardest part of scaling Amazon Bedrock. This guide shows which approach fits your team's requirements, whether that's per-application cost, per-user and per-team cost, per-request granularity, or hard enforcement, and which anti-patterns to avoid

Amazon Bedrock gives you several ways to track and cap cost: application inference profiles, projects, IAM principal attribution, per-request metadata, and a gateway in front of all of it. Teams tend to arrive with the same question: which of these do we actually need, in what order, and do we need all of them? That depends on the outcome you're after. Putting per-team cost on the invoice is a different problem from counting tokens per developer, and both are different from stopping a runaway job before the money is gone.This guide takes a prescriptive, scenario-driven approach. Rather than explaining every feature in isolation, we start with the default recommendation that works for 80% of organizations, then show you how to escalate as your requirements grow — and which anti-patterns to avoid along the way.



Start Here: Choose by the Question You're Answering

Cost tracking on Amazon Bedrock is a layered model, not a single choice. Start with attribution to understand how your users and teams consume Bedrock, then use those patterns to introduce controls and progressive friction that encourage the right behavior. Add each new layer only when a requirement calls for it. The first table below maps goals to layers, and the second shows combinations that typically suit different kinds of organizations.By the question you're answering
if your goal is ...
Layer
Section
Per-application or per-workload cost
Foundation
Application Inference Profiles (bedrock-runtime) or Projects (bedrock-mantle)
Per-user or per-team cost on your bill
Layer 2
IAM Principal Attribution
Per-prompt token usage, sliced by any dimension
Layer 3
Request Metadata Tagging + model invocation logs
Actively stop or throttle spend before it happens
Layer 4
Custom Gateway
By the organization you are
Scenario
Recommended Stack
Small team, just getting started
1 AIP per team + IAM principal attribution + CloudWatch alarms on spend
Multi-team, need chargeback
AIPs per team/app + IAM principal attribution + per-request metadata for operational detail
Claude Code / developer rollout (100+)
LLM gateway (LiteLLM or custom, with per-key budgets) + IAM session tags + per-request metadata + model invocation logs
Multi-tenant SaaS
LLM gateway (off-the-shelf or custom) + per-request metadata for tenant-level tracking + AIPs for aggregate billing per tenant tier


For most organizations, the Foundation layer alone answers the question. Each section below states the requirement it solves, the approach, the limitations you'll hit, and when to escalate to the next layer.



Foundation — Per-Application Cost Buckets: Application Inference Profiles or Projects

Most cost questions come down to which application or team is spending the money. Bedrock answers that on the invoice itself: you create a cost bucket, tag it, and the spend shows up in Cost Explorer and CUR 2.0 under that tag, with no log pipeline to run and no cost estimation on your side. That is why it comes first. There are two mechanisms, and which one applies depends on the endpoint you call:
On  bedrock-runtime  (InvokeModel, Converse) → Use  Application Inference Profiles . Create a profile per application/team, attach cost allocation tags, swap the model ARN for the profile ARN. Tagged costs appear in Cost Explorer and CUR 2.0 natively. As documented in  Track, allocate, and manage your generative AI cost and usage with Amazon Bedrock , SCPs can mandate that all traffic flows through tagged profiles. The  multi-tenant cost management pattern  shows how to add graduated CloudWatch alarm levels on top.
On  bedrock-mantle  (Responses, Chat Completions, Anthropic Messages) → Use  Projects . A single project spans all models — no per-model profile needed. Pass the project ID as a header and tagged costs flow to billing. Up to 1,000 projects per account. This is the natural fit for Claude Code deployments and teams using OpenAI-compatible SDKs.
The practical trade-off is resource count: application inference profiles are model-specific, so the number you manage grows with every model you use, whereas a single project on  bedrock-mantle  can span many models at once. If you're on  bedrock-runtime , profiles are your only option; if you're on  bedrock-mantle  and want one construct across models, projects are the simpler choice.
Limitations: Both methods produce aggregated cost per day per usage-type — no per-request rows. Neither provides enforcement (no "stop at a set limit"). AIPs don't scale to thousands of individual developer profiles. Projects don't cover  bedrock-runtime  features (Agents, Knowledge Bases, Guardrails).
Recommended when: You need cost allocation by team AND application for finance/chargeback, your teams are disciplined, and you don't yet need hard spending caps.



Layer 2 — Per-User & Per-Team Cost: IAM Principal Attribution

Once you have per-application cost buckets, the next question is usually "but which user or team inside that application is driving the cost?" Amazon Bedrock answers it for free: it automatically records the  IAM principal  — user or role — for every inference call on  bedrock-runtime , and that identity flows into AWS Cost Explorer and CUR 2.0 with no application changes: no profiles to create, no headers to pass, no metadata to attach.
To add dimensional context such as team, department, or cost center,  tag your IAM users and roles  with standard AWS tags and activate them as cost allocation tags in the Billing console. Tagged data becomes available in billing the following day.
Where many developers share a single gateway role, session tags applied during  AssumeRole  preserve per-user identity through that role. The pattern is to assume the role per user, cache the resulting credentials for the session lifetime, and carry the user identity as a session tag, a  RoleSessionName , or both.
Limitations: Tagged data appears in billing roughly 24 hours later, and cost allocation tags must be activated in the management account. CUR files grow, since each principal adds a row per usage-type. Most importantly, this layer provides visibility only — it cannot enforce budgets or throttle expensive calls.
Recommended when: You have mature IAM governance, you trust developers with direct model access, and your primary need is after-the-fact chargeback and reporting rather than active control.



Layer 3 — Per-Request Granularity: Request Metadata Tagging

The billing-level approaches (IAM attribution, AIPs, Projects) all aggregate to daily totals. If you need to know "how many tokens did developer X use on experiment Y at 2:30pm on Tuesday?" — you need  per-request metadata tagging .This works by attaching key-value tags to each individual inference call. The tags land in your  model invocation logs  (S3 or CloudWatch Logs), not in CUR. You then query the logs with CloudWatch Logs Insights to produce per-user, per-model token totals:
fields requestMetadata.user as user, modelId,
input.inputTokenCount as inTokens,
output.outputTokenCount as outTokens
| stats sum(inTokens) as totalInput,
sum(outTokens) as totalOutput,
count() as calls
by user, modelId
Request-level attribution is supported on InvokeModel, InvokeModelWithResponseStream, Converse, and ConverseStream. The  multi-tenant cost tracking blog  demonstrates how passing tenant-specific identifiers transforms standard invocation logs into rich analytical datasets.
Keep billing tags stable and low-cardinality (team, environment, application), reserve high-cardinality values (session ID, trace ID, experiment ID) for request metadata, and set that metadata in a single shared layer all traffic passes through rather than relying on individual developers. See the  best practices guidance  for detail.
Limitations: This data never touches billing reports — you must convert token counts to cost yourself, and that figure is only an estimate: it does not reflect discounts, commitments, batch pricing, or provisioned throughput. Application code must be modified. There's no enforcement. You need Model Invocation Logging enabled (additional S3/CloudWatch cost) and an analytics pipeline (Athena/QuickSight) to make the data useful.
Recommended when: You need operational analytics — A/B experiment attribution, per-developer tracking for coaching, multi-tenant SaaS metering — and you're combining it with a billing-level method for finance.



Layer 4 — Hard Enforcement: LLM Gateway (Off-the-Shelf or Custom)

Everything so far is attribution-only; none of it can stop a runaway workload before the spend happens. Hard enforcement — denying a request before it reaches Bedrock — requires a gateway, and the first decision is buy vs. build.
Buy / adopt (start here for most teams). A purpose-built gateway like  LiteLLM  already provides virtual keys per user/team, hard budget caps, rate limiting, and per-key spend tracking in front of Amazon Bedrock, giving you enforcement in days rather than weeks. None of that depends on the wire format your clients speak: LiteLLM exposes OpenAI-compatible routes, Anthropic's   /v1/messages  , and  pass-through routes  that keep native Bedrock request shapes, and the same budgets and keys apply across all of them.
 Kong AI Gateway  does the same from an API-gateway angle, adding cost-based budget caps per consumer group, semantic caching, and prompt compression — see  Unlock advanced AI control with Kong AI Gateway and Amazon Bedrock .
If your rollout is specifically Claude Code and Claude Desktop, the  Claude apps gateway for AWS  is the purpose-built option: a self-hosted container that authenticates developers against your IdP instead of putting AWS credentials on their machines, routes all inference to Bedrock through a single IAM role, and reports per-user usage — the  AWS reference deployment  ships an admin console for per-user spend limits and model access.The one caveat across all of them: they typically call Bedrock through a single service role, so use session tags /  RoleSessionName  to preserve per-user identity in native billing.
Build. When you need deeper AWS-native integration, you don't have to start from an empty Lambda.  AgentCore Gateway inference provider targets  give you a managed enforcement point in front of Bedrock (or any provider endpoint): you declare which models are reachable — including glob patterns such as  anthropic.claude-opus-*  — set per-model token limits, rewrite request paths, and hold the upstream credential in the gateway instead of on the client. On top of that you can layer  rate limits per caller, target, or tool , which reject over-quota requests with a 429. Where you need budget logic those managed controls don't express — cumulative month-to-date spend per team, for instance — build a serverless proxy (API Gateway + Lambda + DynamoDB) that checks each request against per-user/per-team budgets and returns 429 when exceeded. Rather than reinvent it, start from the published references:  Guidance for Tracking and Managing Costs on Amazon Bedrock , the  Multi-Tenant Generative AI Gateway , the proactive cost management series ( Part 1  /  Part 2 ), and  Dynatrace's AI gateway architecture .
Either way, use SCPs to deny direct Bedrock access outside the gateway role, making it the only call path — and the single place where per-request metadata is stamped automatically. Beyond budgets, a gateway is also where model gating, loop protection for agentic tool-use, and cache-aware cost accounting live.
Limitations: A gateway adds latency, is a single point of failure (its outage blocks all AI access), needs careful streaming design, and doesn't feed CUR natively. If it re-assumes an IAM role per user, cache those credentials for the session lifetime — calling  sts:AssumeRole  per request will exceed STS quotas under load.
Recommended when: You're rolling out Bedrock to 100–1,000+ developers (especially Claude Code), you've had or fear a runaway spend incident, or compliance requires provable budget controls.

Decision Flowchart





Anti-Patterns

1. Creating 1,000 Application Inference Profiles for per-developer tracking.
AIPs are designed for team/application granularity, not individual developer attribution. If you need per-developer visibility, IAM principal attribution gives it to you automatically — or use per-request metadata for per-call detail. Don't create an AIP explosion that hits service quotas and becomes an admin nightmare.
2. Using per-request metadata as your billing source of truth.
Request metadata lives in invocation logs, not in CUR. The  FAQ is explicit : "the computed figure is an estimate — it does not reflect discounts, commitments, batch pricing, free tier, or provisioned throughput." Use native billing methods (IAM attribution, AIPs, Projects) for finance-grade cost allocation. Use metadata for operational analytics only.
3. Relying on developer discipline for tagging.
The  best practices documentation  warns: "Per-call tagging mechanisms (request metadata, session tags) are opt-in. Bedrock does not reject calls that omit them." For billing-level attribution, you can enforce tagging across the organization with  Service Control Policies  that deny any invocation not made through a tagged Application Inference Profile Enforce Amazon Bedrock Usage Through Tagged Application Inference Profiles Using SCPs. These SCPs block bad requests but don't fix them, so developers still have to react to the denied call and correct it. For per-request metadata, which SCPs can't enforce, stamp tags automatically in a shared client wrapper or LLM gateway.
4. Putting high-cardinality values in cost allocation tags.
Session IDs, timestamps, or conversation IDs as resource/principal tags create a cardinality explosion in CUR and Cost Explorer. These values belong in request metadata (which lands in logs, not billing). Keep cost allocation tags stable and low-cardinality: team, environment, application, cost center.



Authors

Any opinions in this article are those of the individual author and may not reflect the opinions of AWS.
Enjoyed reading this content? Let the author know!

Your likes, comments, shares, and saves help creators reach more builders.

Loading recommendations

Loading article