AI Engineering
AI Agent Cost Controls: Stop Runaway Loops Before the Bill Grows
Set AI agent budgets with call limits, token ceilings, tool quotas, and clear stop conditions so a failed task cannot quietly become an expensive loop.
In this article
An AI agent doesn't need to be malicious to run up a bill. It can keep rewriting a draft, repeat an unsuccessful search, or launch another worker because its first attempt wasn't conclusive. If every step is allowed to spend independently, a small task can become a surprisingly large expense.
AI agent cost controls should sit outside the model's own judgement. The agent can suggest another attempt, but application code should decide whether the task has budget left. This guide focuses on predictable spending and graceful stops, not provider pricing, which changes and should be checked directly before deployment.
Define the unit you are budgeting
A monthly account limit is useful, but it doesn't explain which task consumed the money. Give each user request a run identifier and track its model calls, input tokens, output tokens, tool calls, and elapsed time. When a task creates child workers, include their usage in the same parent budget.
Separate three controls: a per-run ceiling, a per-user allowance, and an account-wide emergency stop. A generous per-run limit can still exhaust an account when many users submit jobs together. Conversely, an account-wide limit alone may let one broken job consume everyone else's capacity.
The OWASP AI Agent Security Cheat Sheet identifies resource controls as part of agent safety. Treat spending as an application boundary rather than a polite instruction in a prompt. A prompt saying “be economical” is not an enforceable quota.
Put hard limits around every expensive action
Before each call, check whether enough budget remains for its maximum allowed output and associated tool work. Where actual usage arrives after the request, reserve a conservative amount first and reconcile later. Otherwise concurrent calls can each see the same unused balance and collectively overspend it.
For a fictional document-summary job, a configuration might look like this:
{
"max_model_calls": 8,
"max_tool_calls": 12,
"max_elapsed_seconds": 180,
"max_output_tokens_per_call": 1200,
"max_child_workers": 2,
"on_budget_exhausted": "return_partial_result"
}These numbers are an illustrative starting point, not a benchmark or provider recommendation. Test limits against representative tasks. Use JSON Formatter for a sanitised configuration review, then enforce the values in code. Valid JSON doesn't make a budget effective.
Detect repetition before it becomes a loop
Count attempts by operation, not only by total calls. Three searches for the same query may be reasonable if conditions changed; ten identical searches with identical errors usually aren't. Record a fingerprint of the operation, its inputs, and the relevant result category without retaining sensitive payloads.
Stop when the same failure repeats without new evidence. Other useful stop conditions include no meaningful progress, an unavailable dependency, a missing permission, or a task whose next action requires human approval. Don't let the agent reinterpret a permission denial as an invitation to find another route.
Decide what “progress” means for the workflow. In a report job it could be another verified source or a completed section. In a data-processing task it could be another validated record. Merely producing more prose shouldn't reset the progress timer.
Keep retries inside the original allowance
A retry isn't a new task with a fresh budget. Charge it to the same run, including repeated context. Cap retries separately for each dependency, and distinguish transient failures from permanent ones. A network interruption can justify another attempt; an unsupported operation usually cannot.
Watch hidden fan-out. A planner that asks five agents to investigate five topics can create 25 searches before writing anything. Allocate child budgets from the parent pool and make cancellation propagate to every worker. A parent task shouldn't report completion while its background children continue spending.
Also cap downloaded content and retained context. Repeatedly inserting entire documents into a conversation increases input usage and makes the agent harder to inspect. Retrieve only the sections needed for the current step, while preserving enough context to avoid misleading conclusions.
Estimate costs without pretending the estimate is exact
Use current official prices for the models and tools you actually call. Estimate input, output, and any charged tool operations separately. If a service offers caching or batch discounts, only count them when the request qualifies and the billing record confirms it.
A simple worksheet can compare normal, difficult, and failed tasks. The important result is the range and the biggest cost driver, not a falsely precise average. Include concurrency and peak demand when modelling a product launch. A cheap single request can still become expensive at scale.
Review configuration changes with JSON Diff. Raising a context ceiling or enabling more workers should receive the same attention as increasing a monetary allowance. Keep the reviewer focused on changed limits rather than a large block of unchanged settings.
Make a budget stop useful to the user
Return what has been completed, what remains unverified, and a clear reason for stopping. Don't disguise a partial result as a finished answer. Offer a resumable checkpoint when the task supports it, but require fresh approval before increasing a sensitive budget.
Test this path intentionally. Force a low call ceiling in staging, simulate a hanging tool, and cancel a parent run with active children. Confirm that new calls stop and that the usage ledger reconciles. See durable workflow checkpoints for preserving completed work safely.
Conclusion
Good cost controls make an agent's worst day predictable. Use shared budgets, reserved usage, repetition detection, and explicit stop states. The aim isn't to make every task finish at any price; it's to deliver useful work without letting a failed plan spend indefinitely.