AI agents in production: controls that stop runaway runs

An agent spent a full night retrying one malformed ticket — the same tool call, again and again, until the API locked the account out by morning. It had succeeded at nothing and billed for everything. Most write-ups about AI agents in production focus on what the agent can do; the runs that actually hurt are the ones that never stop doing it.
Agents fail differently from ordinary software. A normal job crashes and halts, but an agent plans, acts, observes, and loops, so one stuck step turns into hundreds of calls, a climbing bill, and still no result. Reliability here comes less from a smarter model than from limits — timeouts, capped retries, a cost budget, and a way to spot a loop and hand off to a person.
What follows is why agents run away, the specific controls that stop them — per-step and per-run timeouts, retries with backoff and idempotency, token and cost budgets, loop detection — and when escalating to a human beats retrying one more time.
Why AI agents fail differently from ordinary code
An agent fails differently because it runs in a loop it controls. The pattern underneath every agent is plan, act, observe, repeat: the model picks a tool, sees the result, and decides what to do next, with no fixed number of steps. That autonomy is the point, and it is also the risk — a demo handles ten clean tickets, while production hands the agent the one malformed ticket that sends it round the loop without ever making progress.
Ordinary code gives you a clean failure to catch. An agent gives you a run that keeps going: it burns tokens, compounds small errors into a confidently wrong result, and holds resources the whole time. The cost is not theoretical at the portfolio level either.
According to Gartner (2025), over 40% of agentic AI projects will be canceled by the end of 2027, with escalating costs and inadequate risk controls named among the main reasons. The runaway run is one concrete form of both at once. This is why teams adding an AI feature to a live product should treat an agent as a new class of workload inside their production AI systems, not as one more deterministic job.

Put a ceiling on every run: timeouts and iteration caps
No agent run should be able to continue indefinitely. The first layer of control is boring and effective: a wall-clock timeout on each step, a timeout on the whole run, and a hard cap on loop iterations. Timeouts are a long-standing resilience tool — the AWS Builders' Library describes them as the maximum time a client waits before giving up, which keeps a hung dependency from holding resources forever. An iteration cap does the same job for the loop: after N steps with no finished task, the run stops rather than grinding on.
The trade-off is calibration. Set the timeout or cap too low and you kill legitimate work — a research step that genuinely needs twelve tool calls, or a slow but healthy downstream service. Set it from the observed latency and step counts of real runs, not from a guess, and treat a hit cap as a signal to investigate rather than a number to quietly raise. A run that stops short with a clear reason is far cheaper to debug than one that never stopped at all.
Retry transient errors without acting twice
Retries should recover from a blip, not repeat an action. A transient error — a timeout, a brief 503, a rate-limit — is worth retrying; a logic error or a rejected request is not, and retrying it just spends money. The AWS Builders' Library makes two points that matter for agents: retries are "selfish" because they add load to a service that may already be struggling, so cap them and space them with exponential backoff plus jitter rather than hammering in a tight loop.
The sharper danger is side effects. If a tool call creates a ticket, issues a refund, or sends an email, a naive retry can do it twice. The fix is idempotency: attach an idempotency key to each operation, so the downstream service recognises a repeat and returns the original result instead of acting again.
A safe retry policy has a few non-negotiable parts:
- Retry only transient failures — not validation errors, rejections, or logic faults.
- Cap the number of attempts, and back off exponentially with jitter between them.
- Make every write idempotent, so a retried refund or message happens exactly once.
- Record each attempt, so a retry storm is visible rather than hidden inside one run.
Designing this control layer — where the timeouts sit, what counts as retryable, how budgets and escalation interact — is most of the work in making an agent safe to leave running. Our engineers have built agent orchestration with these limits from the start. Build yours with engineers who build production AI agents.
Cap cost and detect loops before they run away
A budget the run can't exceed is the control that would have stopped the all-night retry. Give each task a token and cost budget, measure spend as the run proceeds, and halt when it crosses the line — a hard stop, not a warning no one reads. This sits alongside steady-state efficiency work on token and model cost; here the goal is narrower: stop one run from spending without bound. Pair it with loop detection — if the same action repeats with no change in state, the agent is stuck, and continuing only adds cost, so break and escalate.
When the problem is a specific dependency rather than the agent, the Circuit Breaker pattern applies directly: after a run of failures from one service, the breaker opens and the agent stops calling it for a while instead of retrying into a wall. Microsoft's guidance is explicit that this differs from retry — retry assumes the operation will eventually succeed, while the breaker assumes, for now, that it won't. The honest trade-off with budgets is the same as with timeouts: set the ceiling from real run costs, or a legitimate long task dies at the budget line while you're still tuning it.
When to escalate to a human instead of retrying
Some failures should never be retried; they should be handed to a person. The rule of thumb is reversibility: a failed read can retry safely, but a failed step that would take an irreversible or costly action should stop and wait for a human decision. That line is sharpest in financial operations where a wrong action is costly — a refund or a transfer is not something to retry hopefully. Escalation is also the right answer when the agent's confidence is low or it has already tried and failed, which is where the deeper work on approval gates and blast-radius limits belongs.
Escalation needs somewhere for the work to go. A failed task should land in a queue a person can review — a dead-letter queue, a flagged ticket, an alert — rather than loop or vanish. The specific conditions that should end a run and route it to a human are worth writing down in advance:
- The iteration cap or run timeout is hit before the task finishes.
- The same action repeats with no change in state (a detected loop).
- The next step is irreversible or costly and the agent's confidence is low.
The cost budget for the run is exhausted.
You can't control what you can't see
Every control above depends on visibility into the run. If you can't see each step — which tool it called, how many tokens it used, how long it took, whether it succeeded — then a quiet looping run is invisible until the bill or the locked account arrives. Trace each step and record its cost and outcome, so a budget can act and a loop can be detected. This is the same discipline as failure modes and monitoring in distributed systems, applied to a workload that generates its own control flow, and it belongs in the same observability and alerting stack you already run.
The controls also need an owner. Deciding where timeouts, budgets, breakers, and escalation live — and how they interact so one doesn't undercut another — is an architecture decision, and worth involving a software architect early rather than bolting limits on after the first runaway run. The controls map cleanly onto the failure modes they prevent:
Key takeaways
- An agent fails differently from ordinary code: it loops instead of crashing, so one stuck step becomes a runaway run that burns cost and finishes nothing.
- Give every run a ceiling — per-step and per-run timeouts and a hard iteration cap — so no run can continue indefinitely.
- Retry only transient errors, cap and back off the attempts with jitter, and make every write idempotent so a retry never acts twice.
- A per-run cost budget that halts the run, plus loop detection and a circuit breaker for failing dependencies, stops spend before it runs away.
- Escalate irreversible, low-confidence, or exhausted-budget cases to a human, and trace every step so these controls have something to act on.
Design the limits before the first live run
A production agent needs more than a capable model; it needs the limits that keep it from running away on the inputs a demo never sees. The controls are individually simple — timeouts, capped and idempotent retries, a cost budget, loop detection, a circuit breaker, and a clear escalation path — and the engineering is in how they fit together and who owns them. Put them in before the first live run, measure them against real traffic, and an agent becomes something you can leave running without watching the bill all night.
If you're moving an agent from demo to real tickets and want the reliability layer designed in rather than retrofitted after the first incident, harden your agent before it hits production with our team.
Summarize with AI
FAQ
Interesting For You

MCP integration: connecting AI to the data it needs
What follows explains what MCP standardizes, how tools and resources differ, how to design scoped access with approval gates, and where these integrations tend to break once real traffic and real permissions are involved.
Read article

LLM cost optimization: controlling tokens and model choice
What follows maps where the cost accumulates, which controls reduce it without hurting answer quality, how to choose between caching, routing, and batching, and the instrumentation you need before changing anything in production.
Read article

When an AI agent does something it shouldn't: approval gates and blast-radius limits
You can give an agent real authority without betting the business on its judgment. Grant it the minimum tools and access its job needs, require a human to approve anything irreversible, and cap what any single action can touch. Log every action with its reason, so a mistake stays visible and undoable.
Read article


