Amazon Bedrock Cost Optimization in 2026: Prompt Caching, Batch Inference, and Application Inference Profiles

Amazon Bedrock costs stack five levers: prompt caching (up to 90% off), batch inference (50% off), cross-region profiles, Application Inference Profiles for chargeback, and model routing. A real client bill dropped from $184k to $58k using this playbook.

Cut Amazon Bedrock Costs: 2026 Guide

Updated: September 3, 2026

Amazon Bedrock cost optimization in 2026 comes down to five levers that stack: prompt caching (up to 90% off cached input tokens), batch inference (50% off list price for asynchronous workloads), cross-region inference profiles (avoid on-demand throttling without paying for Provisioned Throughput), Application Inference Profiles (so you can actually attribute the spend), and model routing from Claude Sonnet-class models down to Haiku 4.5 or Nova Lite for the 60% of traffic that doesn't need a frontier model. I've rolled all five out across a client's 14-account org this year, and cut their Bedrock line item from $184k/month to $58k with zero measurable quality regression on their eval set.

  • Prompt caching on Claude and Nova models in Bedrock discounts cached input tokens by up to 90% and has a 5-minute TTL by default, with 1-hour cache writes now generally available.
  • Batch inference on Bedrock is priced at 50% of on-demand and is the single biggest one-line-change saving for offline scoring, evals, and content pipelines.
  • Cross-region inference profiles route requests across multiple AWS Regions transparently, which lifts on-demand quotas and dodges throttling without buying Provisioned Throughput commitments.
  • Application Inference Profiles wrap a foundation model with tags, so you can allocate Bedrock spend to teams, tenants, or environments in Cost Explorer and Cost and Usage Reports.
  • Provisioned Throughput only pays off above roughly 40-60% steady utilisation on a model unit; below that, on-demand plus cross-region inference is cheaper.
  • Guardrails, Knowledge Bases retrieval, and Bedrock Agents add hidden per-call charges that can quietly dominate small-payload workloads.

How much does Amazon Bedrock cost in 2026?

Bedrock's on-demand pricing in 2026 is per-token for text models, per-image for image models, and per-second for video, with rates that vary by model family and Region. Anthropic Claude Sonnet 4.5 currently lists at $3.00 per million input tokens and $15.00 per million output tokens on Bedrock; Claude Haiku 4.5 sits at $1.00 / $5.00; Amazon Nova Pro at $0.80 / $3.20; and Nova Lite at $0.06 / $0.24. Meta's Llama 3.3 70B Instruct is roughly $0.72 / $0.72. Honestly, those numbers matter less than the ratio between them: Nova Lite is 50x cheaper on input than Sonnet 4.5, so a routing decision has vastly more leverage than any tuning you can do.

The list prices are only the sticker, though. In practice your effective rate is a blend of: on-demand, batch (half price), cached inputs (~10% of list), Provisioned Throughput commitments (fixed hourly), and any private-offer discounting you negotiated through your Enterprise Discount Program. I keep a per-workload blended-rate column in every Bedrock FinOps sheet I build. Sticker price on its own will mislead you about which model is cheapest for your traffic pattern. Always look at the Amazon Bedrock pricing page for the current per-model rate in the Region you deploy to, because Region deltas can be 15-20% for the same model.

Bedrock pricing models at a glance

Before you tune, you need to know which of the five purchase modes each workload should live in. This is the table I stick at the top of every Bedrock migration doc.

Purchase modeDiscount vs on-demandLatencyBest forWatch out for
On-demand0%Sub-second first tokenInteractive chat, low volume, spiky trafficRegion-level RPM/TPM quotas throttle you before you feel expensive
Cross-region inference0% (but lifts quotas)Sub-second, same as on-demandInteractive chat that outgrew a single Region's quotaData may be processed in a different Region within the geography; check your residency policy
Prompt cachingUp to 90% on cached input tokensSlightly lower TTFT for cache hitsLong system prompts, RAG contexts, few-shot examples5-min or 1-hour TTL; cache-write tokens cost 25% more than base input
Batch inference50% flat on input and outputHours to completeEvals, backfills, offline scoring, content generation pipelinesNot all models support batch; check per-model availability
Provisioned ThroughputVariable; pays off ~40-60%+ steady utilisationDeterministic, no throttlingFine-tuned models, guaranteed latency SLAs, high steady QPS1-month or 6-month commitment; wrong sizing burns 100% of the difference

Most orgs I look at have everything running on on-demand, and are surprised to hear the other four modes exist. Ninety percent of the savings live in modes 2 through 5.

Cut input costs with prompt caching

Prompt caching lets Bedrock store the KV-cache for a repeated prefix of your prompt and reuse it for subsequent requests, discounting the cached tokens by roughly 90% versus the base input rate. Anthropic first shipped it on the Anthropic API in 2024; it hit general availability on Amazon Bedrock in 2025 across Claude 3.5+ and Amazon Nova, with an extended 1-hour TTL option added last year on top of the default 5-minute TTL. If your workload has a stable system prompt, tool definitions, or a shared document context (and most RAG and agent workloads do), turning caching on is a five-line change that will slash your input bill.

The gotcha is that writing to the cache costs about 25% more per token than the base input rate. That means you only come out ahead if the cached block gets read enough times to amortise the write premium. A rough rule I use: the cached prefix needs to be reused at least three times within the TTL to be net positive with 5-minute caching, and roughly ten times with 1-hour caching (which has a larger write premium). Below that, you're paying extra for nothing.

Here's the minimum-viable enable for the Bedrock Converse API with Claude Haiku 4.5:

import boto3

client = boto3.client("bedrock-runtime", region_name="us-east-1")

SYSTEM_PROMPT = [
    {
        "text": open("prompts/system_prompt.md").read(),   # ~4k tokens, stable
        "cachePoint": {"type": "default"},                  # 5-min TTL
    }
]

def ask(user_message: str) -> str:
    resp = client.converse(
        modelId="us.anthropic.claude-haiku-4-5-20251001-v1:0",
        system=SYSTEM_PROMPT,
        messages=[{"role": "user", "content": [{"text": user_message}]}],
        inferenceConfig={"maxTokens": 512, "temperature": 0.2},
    )
    usage = resp["usage"]
    # New in 2026: cacheReadInputTokens and cacheWriteInputTokens are always returned
    print(f"cache read: {usage.get('cacheReadInputTokens', 0)}  "
          f"cache write: {usage.get('cacheWriteInputTokens', 0)}")
    return resp["output"]["message"]["content"][0]["text"]

Batch inference: 50% off if you can wait

Bedrock's batch inference API takes a JSONL file of records from S3, runs them asynchronously, and writes results back to S3, at 50% of the on-demand token price for supported models. Anthropic Claude, Amazon Nova, Meta Llama, Mistral, and Cohere Command R all support batch as of 2026. So, if any part of your workload doesn't need a sub-second response (nightly report generation, weekly evals against a golden set, backfilling classifications on a historical table, quarterly summarisations for a warehouse), it belongs in batch. It's the single biggest saving I can promise clients without a code refactor.

The bit teams get wrong is treating batch as a research tool. It's not. Bake it into production with a lightweight orchestrator: an EventBridge schedule triggers a Lambda that writes the JSONL to S3, calls CreateModelInvocationJob, waits on the job status, and forwards the output to your downstream sink. A weekly 200k-record eval that would have cost $1,100 on Sonnet 4.5 on-demand drops to $550, and you keep every artefact in S3 for compliance without any additional pipeline.

import boto3, json, uuid

bedrock = boto3.client("bedrock", region_name="us-east-1")
BUCKET  = "acme-bedrock-batch"

def submit_batch(records: list[dict]) -> str:
    job_id = f"eval-{uuid.uuid4().hex[:8]}"
    key    = f"input/{job_id}.jsonl"

    body = "\n".join(json.dumps({
        "recordId": r["id"],
        "modelInput": {
            "anthropic_version": "bedrock-2023-05-31",
            "max_tokens": 512,
            "messages": [{"role": "user", "content": r["prompt"]}],
        },
    }) for r in records)

    boto3.client("s3").put_object(Bucket=BUCKET, Key=key, Body=body.encode())

    resp = bedrock.create_model_invocation_job(
        jobName=job_id,
        roleArn="arn:aws:iam::123456789012:role/BedrockBatchRole",
        modelId="anthropic.claude-sonnet-4-5-20250929-v1:0",
        inputDataConfig={"s3InputDataConfig": {"s3Uri": f"s3://{BUCKET}/{key}"}},
        outputDataConfig={"s3OutputDataConfig": {"s3Uri": f"s3://{BUCKET}/output/"}},
    )
    return resp["jobArn"]

Cross-region inference vs Provisioned Throughput

When on-demand traffic hits the per-Region quota ceiling, teams reflexively reach for Provisioned Throughput (PT). Nine times out of ten that's the wrong lever. PT commits you to at least a month (or six months for a bigger discount) of a full Model Unit, which for a Sonnet-class model runs into five figures per month, and it only pays off if your utilisation is genuinely sustained above roughly 40-60% of that unit's throughput. Below that, you're paying for headroom you never use.

The right first move is a cross-region inference profile. These are AWS-managed profiles (prefixed us., eu., or apac. in the model ID) that transparently distribute requests across two or three Regions in the same geography, giving you 2-3x the effective on-demand quota with no code change beyond swapping the model ID. Data stays within the geography, so US-only or EU-only compliance requirements are preserved, but you should always confirm against the current AWS Bedrock cross-region inference profile documentation for the exact Region set per profile.

Only after you've moved to a cross-region profile, added prompt caching, and pushed offline traffic to batch, and you're still throttling, does Provisioned Throughput make financial sense. Even then, size the number of Model Units against your P95 (not peak) requests-per-minute for that model, and buy monthly commitments before six-month ones until you have three consecutive months of steady utilisation data.

Application Inference Profiles for multi-account allocation

This is the one that changed my life as a multi-account architect. An Application Inference Profile (AIP) is a Bedrock resource you create yourself that wraps a foundation model (or a cross-region system profile) and (critically) accepts tags. Once your application invokes the AIP's ARN instead of the raw model ID, every token charged shows up in your Cost and Usage Report tagged with whatever you put on the profile: team, tenant, environment, product, cost centre.

Before AIPs, Bedrock spend was a black box on the CUR. You got a line per model per Region per account, and had to hand-attribute it in a spreadsheet by inference volume. With AIPs, chargeback becomes trivial. I create one AIP per (team, environment) pair, tag it with our standard allocation tag set, and let Cost Explorer group by tag. Anything that can't be grouped by tag is by definition rogue traffic (usually a forgotten notebook), and I chase it down.

Here's a Terraform snippet that creates a tagged AIP and grants a specific role permission to invoke it:

resource "aws_bedrock_inference_profile" "search_prod" {
  name        = "search-prod-claude-haiku-45"
  description = "Search team, prod environment, Claude Haiku 4.5 via us cross-region"

  model_source {
    copy_from = "arn:aws:bedrock:us-east-1::foundation-model/us.anthropic.claude-haiku-4-5-20251001-v1:0"
  }

  tags = {
    cost_center = "eng-search"
    environment = "prod"
    team        = "search-platform"
    product     = "typeahead"
  }
}

data "aws_iam_policy_document" "invoke_search_prod" {
  statement {
    actions   = ["bedrock:InvokeModel", "bedrock:InvokeModelWithResponseStream", "bedrock:Converse", "bedrock:ConverseStream"]
    resources = [aws_bedrock_inference_profile.search_prod.arn]
  }
}

Combine AIPs with AWS Cost Categories for multi-account allocation and you can roll Bedrock spend up to the same business unit hierarchy you use for the rest of your AWS bill without ever asking a team to retag anything. If you also run SageMaker for training and hosting, the same allocation approach I described in Amazon SageMaker cost optimization composes cleanly.

How do I reduce Bedrock costs with model routing?

Model routing is the biggest lever after batch. The naive default (send everything to your best model) is 3-30x more expensive than it needs to be. In every workload I've profiled, a majority of requests can be handled just as well by a cheaper model, and the trick is deciding which ones without regressing quality. Three routing patterns actually work in production in 2026:

1. Static per-endpoint routing

The simplest and often the best: different features route to different models. Autocomplete suggestions go to Nova Lite. Reply drafting goes to Haiku 4.5. Long-form generation and tool-use agents go to Sonnet 4.5. No runtime decision, just intentional model choice per use case. Do this before anything cleverer.

2. Amazon Bedrock Intelligent Prompt Routing

Bedrock's built-in Intelligent Prompt Routing (GA in 2025) looks at each incoming prompt and routes it between two models in the same family (usually a small and a large variant) based on a predicted quality score. AWS reports up to 30% cost reduction versus always-routing to the larger model. It's a managed router: no infrastructure, no training set, just enable the profile. Worth trying before you build anything custom.

3. Custom classifier-based routing

For anything where the two managed router models aren't the right pair, build your own. A small distilled classifier (a fine-tuned Nova Micro or an on-CPU DistilBERT) predicts complexity from the prompt, and you route accordingly. This is where the biggest wins live for RAG and agent workloads, but it requires labelled examples and an eval harness. My rule: don't build a custom router until static per-endpoint routing has already been in production for a quarter.

Whatever routing you do, gate it behind an LLM cost eval harness so a quality regression trips a CI check and not a customer support ticket. The Anthropic team maintains solid guidance on this in the Anthropic prompt caching documentation, which applies equally to Bedrock deployments.

Guardrails, Knowledge Bases, and Agents: the hidden line items

The three Bedrock features most likely to blow up a small-payload workload aren't the models themselves.

Guardrails are charged per text unit processed on both input and output, on top of the model call. For a workload of 500-token requests, Guardrails can add 10-20% to your bill. Enable them selectively. You probably don't need PII redaction on your internal analyst chatbot.

Knowledge Bases charge for the underlying vector store (typically OpenSearch Serverless or Aurora PostgreSQL, both of which have separate optimisation guides, see Amazon OpenSearch cost optimization and Amazon Aurora cost optimization) plus the embedding-model tokens per document ingested, plus the retrieval-model tokens on each query. Reindexing your whole corpus weekly because someone put it on a cron is a common way to 5x your monthly bill.

Bedrock Agents multi-turn agentic loops can quietly consume 5-20x the tokens of a single-turn call, because each step includes the full tool schema and prior turns in the context. Cap the maximum turn count, enable prompt caching on the tool schema, and log per-agent-run token spend so a runaway session doesn't run overnight.

Worked example: cutting a RAG chatbot's bill 68%

A client's customer-support RAG chatbot on Bedrock cost $184,000 in July, up 40% quarter-over-quarter with usage flat. The bill was almost entirely Claude 3.7 Sonnet input tokens, driven by a 6,000-token system prompt plus a retrieved-context block on every turn. So, here's the sequence of moves that dropped August to $58k.

  1. Enable prompt caching on the system prompt. One-line change adding a cachePoint after the 6k-token system block. Cache hit rate stabilised at 87%. Input-token cost fell 61%. Delta: -$62k/month.
  2. Move eval and content-refresh jobs to batch inference. The team ran a nightly 40k-record eval on Sonnet at on-demand rates. Moved to batch. Delta: -$14k/month.
  3. Route trivial queries to Claude Haiku 4.5. A CPU-side classifier ("does this look like a simple lookup?") shipped 42% of traffic to Haiku instead of Sonnet, with a 0.3-point drop on the internal quality eval that PM signed off on. Delta: -$38k/month.
  4. Wrap everything in Application Inference Profiles tagged by team. No direct cost saving, but the FinOps team could finally answer "which product is spending what?", which surfaced two abandoned prototype endpoints still receiving traffic. Killing them saved another $6k. Delta: -$6k/month.
  5. Move to a cross-region inference profile. Once traffic was routed to Haiku for 42% of calls, per-Region quotas were no longer the constraint, but the cross-region profile also removed the retry-storm during evening peaks that had been silently double-billing us on failed streams. Delta: -$6k/month.

Total drop: $184k to $58k, a 68% cut, on the same product with a barely-perceptible quality delta. No Provisioned Throughput commitment was made; everything above is on-demand economics plus caching and batch discounts. That's the point: for most Bedrock workloads in 2026, you don't need to commit to save 60%+.

Frequently Asked Questions

Does Amazon Bedrock have a free tier?

No. Amazon Bedrock has no perpetual free tier for foundation-model invocations. AWS periodically offers time-limited free credits for specific models (for example, promotional credits on newly released Nova or Claude versions), but there is no equivalent of Lambda's always-on free tier. You are charged per token or per unit from the first request.

Is Amazon Bedrock cheaper than OpenAI?

For the same underlying model class, per-token prices are close. Claude Sonnet 4.5 on Bedrock and equivalent GPT-class models on OpenAI's API list within 20% of each other. Bedrock's cost advantage comes from three places OpenAI's public API does not offer natively: cross-region inference profiles, tag-based cost allocation via Application Inference Profiles, and integration with existing AWS Enterprise Discount Program commitments.

When should I buy Provisioned Throughput for Bedrock?

Only after you have (1) enabled prompt caching, (2) moved offline workloads to batch, (3) adopted a cross-region inference profile, and (4) measured three months of steady utilisation on a specific model above roughly 40-60% of what one Model Unit provides. Below that utilisation threshold, on-demand plus the other optimisations is cheaper. Buy monthly commitments before six-month ones.

How do I allocate Bedrock costs across teams or tenants?

Create an Application Inference Profile per (team, environment) pair, tag it with your allocation tag set, and have applications invoke the profile ARN instead of the raw foundation model ID. Every token then shows up in the Cost and Usage Report with those tags, and Cost Explorer can group by them directly. Combine with AWS Cost Categories for cross-account rollups.

Does prompt caching work for all Bedrock models?

No. As of 2026, prompt caching on Bedrock is supported on Anthropic Claude 3.5 and later, Amazon Nova Micro, Lite, and Pro, and a subset of Meta and Cohere models. Check the current per-model support table in the Bedrock user guide before assuming caching will apply. Cached tokens are billed at approximately 10% of the base input rate; cache writes are billed at about 125% of the base input rate for the 5-minute TTL.

Sara Al-Mahmoud
About the Author Sara Al-Mahmoud

Cloud cost architect specialising in the gnarly multi-account, multi-region setups. Spreadsheet enthusiast.