← Agent Frameworks 🕐 5 min read
Agent Frameworks

Bedrock Reserved Capacity, Savings Plans, and Multi-Account FinOps (2026)

AWS Savings Plans cover four families only:

Amazon Bedrock is not covered by any AWS Savings Plans. This is the most common FinOps misconception for Bedrock workloads.

AWS Savings Plans cover four families only:

  • Compute Savings Plans → EC2, Lambda, Fargate
  • EC2 Instance Savings Plans → EC2 only
  • SageMaker AI Savings Plans → SageMaker AI components
  • Database Savings Plans → Aurora, RDS, DynamoDB, ElastiCache, DocumentDB, Neptune

SavingsPlanCoveredUsage and SavingsPlanNegation line item types will never appear on Bedrock inference CUR rows. The correct Bedrock commitment mechanism is the Reserved Service Tier (GA November 26, 2025).


Reserved Service Tier (GA November 2025)

Bedrock’s native commitment product — distinct from both Savings Plans and Provisioned Throughput.

Structure:

  • Unit: fixed price per 1,000 tokens-per-minute (TPM) reserved capacity, billed monthly
  • Terms: 1-month or 3-month
  • Minimum: 100K input TPM, 10K output TPM (separate input/output allocations)
  • Overflow: automatic spillover to Standard tier when reserved capacity is exceeded — no dropped requests, no 429s
  • SLA: 99.5% uptime for model response
  • Access: requires AWS account team engagement (not self-service console)
  • Models (as of early 2026): Claude Sonnet 4.5, Opus 4.5, Haiku 4.5; expanding

Reserved vs Provisioned Throughput:

Dimension Provisioned Throughput (MUs) Reserved Service Tier
Commitment unit Model Units — opaque throughput bundle 1K TPM — transparent
Input/output separation No Yes
Terms 1-month, 6-month, or no-commitment 1-month or 3-month
Overflow behavior No — throttles at limit (HTTP 429) Yes — spills to Standard
SLA None published 99.5% uptime
Access Self-service console Account team required
Custom model support Yes — required for fine-tuned models No — foundation models only

LiteLLM config for Reserved tier:

model_list:
  - model_name: claude-reserved
    litellm_params:
      model: bedrock/anthropic.claude-sonnet-4-5
      aws_region_name: us-east-1
      extra_body:
        service_tier: "reserved"

Reserved tier utilization: The ResolvedServiceTier CloudWatch dimension shows actual tier served (reserved vs standard overflow) per request — enables direct utilization measurement. Billing reservation charges appear as a separate recurring fee line item in CUR; exact line_item_line_item_type is not yet documented in the CUR data dictionary — validate against live CUR exports.


Provisioned Throughput (Older Model — Required for Custom Models)

PT remains the only path for custom/fine-tuned models. Hourly billing continues until deletion regardless of utilization.

Commitment tiers:

Term Notes
No-commitment Deleteable any time; highest hourly rate
1-month Locked for term
6-month ~38% lower than 1-month for comparable models

CUR line items for PT:

  1. Capacity reservation charge (fixed hourly): line_item_usage_type = {region}-{model}-ModelUnit:{commitment-term} (e.g., USE1-Claude3Sonnet-ModelUnit:1mo). This is the charge you pay regardless of traffic.

  2. Token inference charges (variable): When PT capacity serves requests, token consumption appears with standard usage type patterns. No CUR column cleanly separates PT-served from on-demand tokens — distinguishing requires joining on provisioned model ARN via CloudTrail.

LiteLLM config for PT with on-demand fallback:

model_list:
  - model_name: claude-sonnet-pt
    litellm_params:
      model: bedrock/anthropic.claude-3-5-sonnet-20241022-v2:0
      model_id: arn:aws:bedrock:us-east-1:123456789012:provisioned-model/abc123xyz
      aws_region_name: us-east-1
      tpm: 50000
      rpm: 200

  - model_name: claude-sonnet-ondemand
    litellm_params:
      model: bedrock/anthropic.claude-3-5-sonnet-20241022-v2:0
      aws_region_name: us-east-1

router_settings:
  routing_strategy: usage-based-routing-v2
  enable_pre_call_check: true   # checks limits before request; triggers fallback before 429
  fallbacks: [{"claude-sonnet-pt": ["claude-sonnet-ondemand"]}]

enable_pre_call_check: true is critical — without it, PT throttles return 429 to the caller rather than transparently falling back.

PT utilization tracking:

  • InvocationThrottles CloudWatch metric (dimension: ModelId) — leading indicator of PT saturation
  • OTPS calculation: OutputTokenCount / (InvocationLatency - TimeToFirstToken) — drop below baseline signals throughput pressure
  • CloudWatch does not expose a single “PT utilization %” metric natively

Batch Inference — 50% Cost Reduction

Available for select Anthropic, Meta, Mistral, and Amazon Nova models. Supports Converse API format (GA February 2026) in addition to InvokeModel.

CUR appearance: Same line_item_usage_type format as real-time but at 50% unit price. No distinct “batch” token in usage type — distinguish via line_item_operation = 'CreateModelInvocationJob' or by joining to CloudTrail batch job events.

LiteLLM batch submission:

batch = litellm.create_batch(
    completion_window="24h",
    endpoint="/v1/chat/completions",
    model="bedrock/anthropic.claude-3-5-sonnet-20241022-v2:0",
    input_file_id="<s3-input-uri>",
)

For high-volume async workloads (nightly document processing, model eval pipelines) batch is the single largest cost lever available — 50% reduction with no model or prompt changes.


Multi-Account FinOps

Consolidated billing: Bedrock costs from all Organizations member accounts appear in the management account CUR when consolidated billing is enabled. Key columns:

  • line_item_usage_account_id — member account that generated usage
  • line_item_iam_principal — IAM ARN of caller (CUR 2.0 only; management account activation required)

Cross-account Athena query:

SELECT
    line_item_usage_account_id AS account_id,
    REGEXP_EXTRACT(line_item_usage_type, '-(.*?)-(input|output|cache)', 1) AS model_name,
    SUM(line_item_unblended_cost) AS total_cost,
    SUM(line_item_usage_amount) AS total_tokens,
    DATE_TRUNC('day', CAST(line_item_usage_start_date AS TIMESTAMP)) AS usage_date
FROM cur_database.cur_table
WHERE line_item_product_code = 'AmazonBedrock'
  AND line_item_line_item_type = 'Usage'
  AND line_item_usage_start_date >= DATE_ADD('day', -30, CURRENT_DATE)
GROUP BY 1, 2, 5
ORDER BY total_cost DESC;

LiteLLM as centralized gateway limitation: All Bedrock calls show the gateway’s IAM role ARN in line_item_iam_principal — not downstream application identity. For application-level attribution through a shared gateway, use Application Inference Profiles (one AIP per team/model; tags flow to CUR) or Bedrock Projects (lower maintenance for large multi-tenant deployments).

Cost Categories at management account level map line_item_usage_account_id values to business dimensions (division, product line, environment) for showback/chargeback — 12-month retroactive application available.


FinOps Maturity Model

Crawl — Visibility

  • Enable CUR 2.0 (INCLUDE_IAM_PRINCIPAL_DATA) in management account
  • Activate cost allocation tags in Billing console (24h delay; not retroactive)
  • Tag LiteLLM IAM roles by team/app; build Athena base view on AmazonBedrock line items
  • Set AWS Budget alert at account level

Deliverable: Weekly Cost Explorer report by model and account

Walk — Accountability and Optimization

  • Deploy Application Inference Profiles for multi-tenant attribution through gateway
  • Enable CloudWatch InputTokenCount, OutputTokenCount, InvocationThrottles per ModelId
  • Migrate async workloads to batch inference (50% reduction)
  • Add cache-read and cache-write token columns to CUR reconciliation
  • Set Reserved tier for models with >30 days sustained load above 100K input TPM

Deliverable: Per-team monthly chargeback from Athena; PT/Reserved utilization dashboard; batch savings documented

Run — Unit Economics and Automation

  • Join CUR to LiteLLM SpendLogs for cost per completed transaction
  • Automate Reserved tier right-sizing: weekly CloudWatch TPM query → alert at <60% utilization (over-provisioned) or >2% throttle rate (under-provisioned)
  • LiteLLM model routing by request complexity: Haiku (Flex/cheap) for classification, Sonnet (Reserved) for complex reasoning
  • Cost Categories at management account for cross-P&L chargeback
  • AWS Cost Anomaly Detection scoped to Bedrock → Slack alerts via EventBridge

Deliverable: Real-time cost-per-outcome dashboard; automated reservation right-sizing runbook


Reference Card

Topic Key Fact
Bedrock Savings Plans Do not exist — not covered by any AWS SP type
Bedrock commitment mechanism Reserved Service Tier (Nov 2025) + Provisioned Throughput
Reserved tier unit 1K TPM; 1- or 3-month; min 100K input TPM; requires account team
PT unit Model Units; 1- or 6-month; no overflow — throttles at limit
Batch discount 50% off on-demand
Cross-account CUR column line_item_usage_account_id
IAM attribution column line_item_iam_principal (CUR 2.0 only; mgmt account activation)
LiteLLM PT routing model_id = provisioned model ARN; enable_pre_call_check: true
LiteLLM Reserved tier extra_body: {service_tier: "reserved"}
PT utilization proxy InvocationThrottles + OTPS calculation
Reserved utilization ResolvedServiceTier CloudWatch dimension

Sources: AWS Bedrock pricing, AWS Savings Plans eligible services docs, Bedrock Reserved Service Tier announcement (Nov 2025), Bedrock CUR data dictionary, LiteLLM routing docs, FinOps Foundation re:Invent 2025 recap.