Any page that prints a table of Bedrock per-model token rates is wrong within a quarter, and the ones that are wrong are worse than useless because they look authoritative. What is stable is the structure: what the unit is, which four variables move a rate, and how to fetch the current number in a script. That is what this page is.
The unit, and the unit trap
Bedrock’s on-demand pricing is per token, with input and output priced separately and output almost always higher — for mechanical reasons rather than commercial ones, since generation is memory-bandwidth bound in a way prefill is not.
The trap is the denominator. AWS has published Bedrock rates per 1,000 tokens and per 1,000,000 tokens at different times and in different places, and the underlying Price List data uses its own unit strings. A spreadsheet that mixes the two is out by a factor of a thousand, which is the single most common error in internal cost models for this service. Whenever you copy a rate, copy its unit into the same cell.
Your own token counts come from the responses, not from an estimate: every Converse response carries usage.inputTokens, usage.outputTokens and usage.totalTokens, and a completed batch job writes inputTokenCount and outputTokenCount for the whole run into manifest.json.out. Multiply those by the current rate and you have an actual figure rather than a modelled one.
Four things that change the rate
- The model. Obviously — but note that a model family has several members at very different prices, and that the id you pass includes a version. Upgrading from one dated version to the next is a price change as well as a behaviour change.
- The Region. Rates differ between Regions for the same model. With cross-region inference AWS documents that the price is calculated from the Region you call the profile from, not the one that served the request — so a geographic profile does not expose you to another Region’s pricing. A global profile is documented as offering approximately 10% savings over standard pricing.
- The direction. Input and output are separate rates. Any cost model that uses a single blended rate will misprice anything with a long prompt and a short answer, which describes most retrieval-augmented workloads.
- The mode. On-demand, batch, provisioned and cached reads are different line items for the same model. See below.
Batch, caching and the other line items
AWS’s Bedrock pricing page describes batch inference as priced 50% below on-demand for supported foundation models, at the time of writing. That is the largest single lever available to most workloads and it costs nothing but latency — it is worth auditing what fraction of your traffic genuinely needs a synchronous answer before optimising anything else.
Prompt caching appears as two extra rates rather than a discount on one: a cache write rate above the normal input rate, and a cache read rate well below it. That shape means caching is only economic when the cached prefix is read many times — writing a large system prompt to cache once and reading it twice can cost more than not caching at all. Your usage block reports cacheWriteInputTokens and cacheReadInputTokens separately, which is the data you need to check whether it is paying.
Guardrails are metered separately again, in text units per policy — the usage object on a guardrail assessment breaks out topicPolicyUnits, contentPolicyUnits, sensitiveInformationPolicyUnits and others. Applying a guardrail to an entire retrieved corpus on every turn is a real cost, and the reason guardContent scoping exists.
The 50% batch figure and the 10% global-profile figure are as published by AWS at the time of writing, August 2026, on the Amazon Bedrock pricing page and the cross-Region inference documentation. Both are the kind of number that moves. No per-model token rate is quoted on this page deliberately — fetch them, do not copy them.
Getting the current numbers programmatically
Bedrock rates are in the AWS Price List, which means you can query them rather than screen-scrape a marketing page. The service code is AmazonBedrock.
# What attributes can I filter on?
aws pricing describe-services \
--service-code AmazonBedrock \
--region us-east-1
# Current on-demand rates, filtered down
aws pricing get-products \
--service-code AmazonBedrock \
--region us-east-1 \
--filters 'Type=TERM_MATCH,Field=regionCode,Value=us-east-1' \
--format-version aws_v1 \
--max-results 100
Two operational notes. The Price List API is only available in a small number of Regions, so the --region above is the API endpoint rather than the Region you are pricing — that is what the regionCode filter is for. And the response is deeply nested JSON with the rate under terms.OnDemand; run describe-services first and read the attribute names, because they are the only reliable guide to how models are labelled this quarter.
The reason to do this at all is that it turns a stale spreadsheet into a job. A weekly script that pulls current rates, multiplies by last week’s measured token counts and writes the result somewhere visible is perhaps thirty lines, and it is the difference between knowing what you spend and knowing what you spent when somebody last checked. Pair it with a Budgets alert on Bedrock spend so the surprise arrives as a notification rather than as an invoice.
What is not in the token price
The per-token rate is not the bill. Four other things commonly show up:
- The vector store. A knowledge base implies an OpenSearch Serverless collection or equivalent, billed by capacity whether or not anybody queries it. AWS notes that deleting a knowledge base does not delete the vector store, so this cost outlives the thing that created it.
- Embedding calls during ingestion. Every re-ingestion of changed documents is embedding tokens, and semantic chunking additionally uses a foundation model at ingestion time.
- Provisioned Throughput. Billed hourly from creation until deletion regardless of traffic, and undeletable inside a commitment term — see the break-even calculation.
- Retried and failed requests. A throttled request that your SDK retried four times before succeeding is billed for what it consumed on the attempts that produced tokens.
Bedrock’s bill is per account and per model; it does not know which of your teams or customers generated a call. The one hook the API gives you is requestMetadata on Converse — up to 16 key-value pairs you can filter invocation logs on — and using it consistently is the difference between attributable spend and a single large number. A gateway like Multigrid does the same job at the layer above, tagging and aggregating per key across providers, which matters once Bedrock is not the only place your requests go.
Top comments (0)