AWS has no setting that stops Bedrock at a dollar figure. What it has is a budget that can attach an IAM policy on your behalf, and a deny policy that removes invoke permission. That composition is a real control — but it is bounded by how fast AWS knows what you spent, and that bound is the first thing to understand.
What a hard cap can and cannot mean
AWS Budgets evaluates against cost and usage data, and that data is refreshed on a periodic cadence rather than continuously. The practical consequence is that between the moment your spend crosses a threshold and the moment the budget notices, an unbounded amount of further spend can occur. A runaway loop calling a large model in parallel can spend a great deal inside that window.
So this control is not a circuit breaker. It is a backstop: it guarantees that spend eventually stops rather than continuing for the rest of the month, and it converts an open-ended incident into a bounded one. If what you need is a genuine per-request refusal at a spend limit, that has to live in your own application path — see setting a per-request cost ceiling, which enforces before the call rather than after the bill.
Build both. The application-side ceiling catches the single expensive request; the budget action catches the pattern of many cheap ones that nobody noticed.
The deny policy
Create a managed policy that denies Bedrock inference and nothing else. Keeping it narrow matters: a budget action that attaches a broad deny takes down more than the model calls, and the recovery from that is worse than the overspend.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "BedrockEmergencyStop",
"Effect": "Deny",
"Action": [
"bedrock:InvokeModel",
"bedrock:InvokeModelWithResponseStream",
"bedrock:Converse",
"bedrock:ConverseStream"
],
"Resource": "*"
}
]
}
Naming all four actions is deliberate. The Converse API is the modern surface and InvokeModel the older one, and applications in a large account are usually using both because different SDKs and different generations of code reach for different ones. An explicit deny beats any allow, so this policy attached alongside a permissive role wins.
What it does not cover is worth stating. Agent invocation, knowledge base retrieval, and model customisation jobs are separate action strings, and a customisation job already running is not stopped by removing invoke permission. If those are material to your bill, add their actions; check the Bedrock section of the AWS service authorization reference for the current list rather than guessing at names.
The budget and its action
AWS Budgets documents budget actions as applying an IAM policy or a service control policy, or targeting specific EC2 or RDS instances, and each action can be configured to run automatically or to wait for manual approval. Multiple actions can fire at the same threshold. AWS documents budget actions here.
- Create a cost budget scoped to Bedrock. Filter by service, and if you want per-team caps, filter by the cost allocation tag from the tagging page — that tag has to be activated first or the filter will match nothing.
- Add notification thresholds well below the action threshold. An action at 100% with no warning at 60% and 80% is a control that only ever communicates by breaking things.
- Attach the budget action at the threshold you are willing to stop at, targeting the managed policy above and the roles or groups that call Bedrock.
- Decide approval mode. Automatic execution is the only mode that works overnight; manual approval is the only mode that cannot take down production by surprise. For a shared account, run automatic in non-production and manual in production.
- Test it by setting a temporary budget of a few dollars against a test role, letting it fire, and confirming both that the policy attached and that you know how to detach it.
That last step is the one people skip and regret. Reversal is manual — the budget attaches the policy but does not remove it when spend rolls into a new month — so somebody has to know the detach command before the incident, not during it.
The execution role
Budgets acts through a role you create and hand it. That role needs to be assumable by the budgets service principal and to hold exactly the permissions the action requires — for a policy-attach action, the IAM permissions to attach that specific policy to those specific principals.
Scope the resource ARNs. A role that can attach any policy to any principal is a privilege escalation path that happens to be labelled cost management. Constrain the policy ARN to the one managed policy above and the principal ARNs to the roles you intend to stop, and the blast radius of the role matches the blast radius of the control.
An IAM deny is all-or-nothing: at the threshold, the feature that calls Bedrock stops working. If the goal is to bound spend rather than to stop serving, the alternative shape is to route the same traffic to a cheaper model or a different provider when a budget signal fires — which means one call site that can address several providers, rather than an SDK client bound to one. That is what an LLM gateway like Multigrid is for: a single API across providers, with the routing and per-key spend accounting in front of it, so “over budget” can mean degrade instead of stop.
The gap between spend and enforcement
Three things narrow the window between overspending and stopping, and none of them is the budget.
- Bedrock invocation logging plus a metric filter. Model invocation logs can be delivered to CloudWatch Logs, and a metric filter over input and output token counts gives you a near-real-time volume signal, which is a far better alarm input than a daily-refreshed dollar figure. Token volume is not cost, but it is proportional to it within a model.
- Service quotas on requests and tokens per minute. Bedrock enforces per-model throughput quotas, and lowering the requested quota for a model is a genuine rate ceiling that applies immediately. Find the exact quota names in the Service Quotas console under Amazon Bedrock; they are per-model and per-region.
- An application-side ceiling. The only control that can refuse a specific request before it is billed is one that runs before the call.
Put together, the layered shape is: a per-request ceiling that refuses the pathological call, a quota that bounds the rate, an alarm on token volume that pages a human in minutes, and a budget action that guarantees the month ends. Only the last of those is what the phrase “hard spend cap” usually means, and it is the slowest one.
Top comments (0)