Bedrock economics, wired up

Chapter 11 said inference profiles are routing and quotas are physics; this chapter makes them concrete, ARNs you create, model units you commit to, service-quota names you request increases against, and a per-tenant cost-attribution setup you can deploy. This is the SME layer under the model plane's economics: not "caching saves money" but which ARN you pass, which tag carries the cost, and which quota throttles first. Every follow-along here is labeled illustrative because this box has no AWS account, but the shapes are the shapes.

Inference profiles: two kinds, two ARNs

An inference profile is the thing you actually pass as modelId, and there are two species that solve two different problems.

System-defined (cross-region) profiles solve capacity. AWS publishes them per model with a region-prefix id, and passing one routes each request across a pool of regions so a single region's bad day is not yours:

us.anthropic.claude-opus-4-8      # routes across US regions
eu.anthropic.claude-opus-4-8      # across EU regions (a residency choice)
apac.anthropic.claude-opus-4-8    # across APAC regions
global.anthropic.claude-opus-4-8  # the largest pool, all regions

You do not create these; you reference them, and for the newest Claude models a bare regional id often is not offered at all, so the profile is the only door. The ARN form is arn:aws:bedrock:us-east-1:ACCOUNT:inference-profile/us.anthropic.claude-opus-4-8.

Application inference profiles solve cost attribution. You create one, wrapping a system-defined profile or a foundation model, and tag it, and every invocation through it is attributable to those tags in Cost Explorer:

# illustrative (boto3 bedrock control plane)
bedrock.create_inference_profile(
    inferenceProfileName="tenant-acme-opus",
    modelSource={"copyFrom":
        "arn:aws:bedrock:us-east-1::inference-profile/us.anthropic.claude-opus-4-8"},
    tags=[{"key": "tenant", "value": "acme"},
          {"key": "team", "value": "search"}],
)
# -> returns an application-inference-profile ARN you pass as modelId

The resulting ARN is arn:aws:bedrock:us-east-1:ACCOUNT:application-inference-profile/ID, and that is what your per-tenant worker passes as modelId. This is the wire-level answer to the multi-tenancy chapter's "who spent this": create one application profile per tenant, tag it, and the showback breakdown falls out of Cost Explorer keyed by the tenant tag, no custom metering required.

The both-ARNs IAM gotcha. An application inference profile that routes across regions needs bedrock:InvokeModel permission on two resources: the profile ARN and the underlying foundation-model ARNs in every region it can route to. Grant only the profile and you get an AccessDeniedException that names a region you never explicitly called, which is baffling until you know the routing is doing it. The IAM policy must list arn:aws:bedrock:*::foundation-model/anthropic.claude-opus-4-8 alongside the profile. This one trips up nearly every first cross-region deployment.

A per-tenant cost-attribution scenario

Concretely, for Hive's multi-tenant platform: at onboarding, a setup step creates an application inference profile named tenant-<id>-<tier>, tagged with the tenant id and their plan, and stores the returned ARN in the tenant's config. Every worker for that tenant loads the ARN and passes it as modelId. Now three things are true at once: Cost Explorer shows spend per tenant tag (finance is happy), the budget ledger cross-checks its own token accounting against the AWS bill per profile (drift is detectable), and a tenant's model access can be revoked by archiving one profile (offboarding is one call). The application profile is where the book's tenant-isolation and cost-attribution chapters become one AWS resource.

Provisioned throughput: buying a floor

On-demand pricing is per-token with shared quota; provisioned throughput buys dedicated capacity by the hour, and the unit is a model unit (MU), each delivering a published per-model throughput of tokens per minute. You create it, optionally with a commitment for a discount:

# illustrative
resp = bedrock.create_provisioned_model_throughput(
    modelUnits=2,
    provisionedModelName="checkout-agent-floor",
    modelId="arn:aws:bedrock:us-east-1::foundation-model/anthropic.claude-opus-4-8",
    commitmentDuration="OneMonth",     # or SixMonths, or omit for no-commit
)
provisioned_arn = resp["provisionedModelArn"]   # pass this as modelId

The economics: no-commitment provisioned throughput is billable by the hour and cancelable, so it is a way to guarantee a floor of capacity for a latency-sensitive path without the shared-quota lottery; committed (one or six month) trades flexibility for a lower rate. The decision rule from Chapter 14, sharpened: a steady predictable base of interactive traffic worth an SLA gets a provisioned floor; the spiky overnight fleet stays on-demand, because paying for idle committed MUs overnight is exactly the waste provisioning is supposed to prevent. A common production shape is both: a small provisioned floor under the interactive product, the fleet on-demand and governed.

Quotas and throttling, by name

The governor shapes demand against quotas; here are the quotas it shapes against. Bedrock's on-demand limits are Service Quotas with per-model names of the form "requests per minute for Anthropic Claude Opus 4.8" and "tokens per minute for Anthropic Claude Opus 4.8", set per account per region. Exceed either and the API returns a ThrottlingException (HTTP 429), which is the exact signal the token-bucket lab had the fleet avoid producing. Two SME facts:

  • Cross-region inference raises effective throughput. Because a system-defined profile spreads load across regions, its aggregate ceiling is higher than any single region's quota, which is a capacity lever and the reason your quota math must be done against the profile's behavior, not one region's number.
  • Increases are per-model, per-region, via Service Quotas. A quota increase request names the specific model and region; there is no global "more Bedrock" knob. Plan the request against the fleet-sizing arithmetic: you know the tokens per minute your fleet needs before you ask.

Observability of the spend

The last wire-level piece: how spend and errors reach a dashboard. Model invocation logging, enabled once per account, delivers every request and response to CloudWatch Logs and/or S3:

# illustrative
bedrock.put_model_invocation_logging_configuration(loggingConfig={
    "cloudWatchConfig": {"logGroupName": "/bedrock/invocations",
                         "roleArn": LOG_ROLE},
    "s3Config": {"bucketName": "hive-bedrock-logs"},
    "textDataDeliveryEnabled": True,
})

Each log record carries the model id, region, the input and output bodies, token counts, and the inference region actually used (which for a cross-region profile tells you where a request landed, invaluable when a residency question or a regional slowdown appears). Alongside the logs, the AWS/Bedrock CloudWatch metrics namespace publishes InputTokenCount, OutputTokenCount, Invocations, InvocationLatency, InvocationClientErrors, and InvocationThrottles, and the last one is the metric your on-call quota-storm alarm watches: a rising InvocationThrottles is the fleet brushing the quota, exactly the page the governor exists to prevent.

Don't be confused: application inference profile vs provisioned throughput. Both create an ARN you pass as modelId, and both are "a thing you set up in advance", but they do opposite jobs. An application inference profile changes nothing about capacity or price; it is a tagging wrapper for cost attribution over on-demand (or cross-region) inference. Provisioned throughput changes the capacity and billing model: dedicated MUs billed by the hour. You can even combine them conceptually, attribute cost with a profile, guarantee capacity with provisioning, because they operate on different axes. Confusing them leads to teams "provisioning" when they only wanted per-tenant cost reports, and paying by the hour for a tagging feature.

👉 Next: Guardrails, batch, and Knowledge Bases, the three Bedrock surfaces an agent platform reaches for most after the model itself, with their real config shapes and a scenario each.