AI Agents · Cost Control · Production

How we stopped a runaway agent from burning €180 in a weekend

Published · Updated

An autonomous content agent got stuck in a retry loop and burned through its monthly budget in 48 hours. Here is the guardrail stack we built to make sure it never happens again.

The alert fired at 02:14 on a Sunday. A production agent designed to draft and publish short-form posts had entered a retry storm after a downstream API started returning intermittent 500s. By the time we woke up on Monday, it had made 14,300 LLM calls, generated 9,800 near-identical drafts, and cost us €180. The work it produced was unusable. That weekend was the catalyst for what we now call the budget envelope: a hard, observable ceiling on every agent we ship.

The failure mode we kept hitting

Most agent loops are not exotic. They are three patterns repeating: retry storms on flaky upstreams, recursive planning that calls itself, and memory growth that pushes prompts past token limits and triggers fallback models. Each one is cheap per iteration and catastrophic in aggregate. We measured our last six incidents and three of them were pure retry loops, two were runaway planners, one was a memory leak. None of them were caught by latency alerts because the agent was technically making progress, just useless progress.

Designing the budget envelope

We treat every agent as having three independent budgets: a per-run ceiling, a daily aggregate ceiling, and a per-task token ceiling. The per-run ceiling is enforced synchronously inside the orchestrator before each LLM call. The daily ceiling is checked against a shared counter in Redis with a TTL. The per-task ceiling is computed from expected input size plus a generous margin, and any call exceeding it is rejected before it leaves the process. All three are logged with structured fields so we can graph burn rate per agent, per tenant, per model.

The kill switch that actually fires

A budget without a kill switch is just a post-mortem tool. We wired each agent to a heartbeat that emits to a lightweight watchdog. If the watchdog sees burn rate exceed 3x the rolling 7-day median for more than 90 seconds, it flips the agent's state to paused in the control plane and the next scheduled tick short-circuits. In the retry storm incident, this would have stopped the agent after roughly €9 of waste instead of €180. We tested the kill path with a synthetic load test before trusting it in production, because a kill switch you have never fired is a kill switch you do not have.

Trade-offs we accepted

Strict ceilings cost us throughput. During one peak week our publishing agent hit its daily cap twice and we had to manually raise it, which is a smell we now treat as a feature, not a bug. The manual override forces a human to look at why the agent needed more than its allocated budget. We also learned that ceilings need to be per-tenant, not global, because a single noisy customer can starve everyone else. The Redis counter pattern is simple but it adds a network hop on every call, which we measured at roughly 4ms p50.

What we measure now

Every agent ships with a dashboard panel showing four numbers: calls per hour, cost per hour, rejection rate, and the ratio of successful outputs to total calls. The last metric is the one that catches the dangerous cases where the agent is technically running but producing nothing useful. We also keep a rolling 30-day cost per successful task, and any agent whose ratio drifts above 1.5x its baseline triggers a review. None of this is glamorous, but it is the difference between an agent you trust in production and an agent you babysit.

Pragmatic takeaway

If you ship autonomous agents, assume they will misbehave in boring, repeatable ways and budget for that explicitly. A per-run ceiling, a daily aggregate, a kill switch wired to a watchdog, and a cost-per-success metric are the minimum viable guardrail stack. Build the kill path before you need it, test it under load, and accept that strict ceilings will occasionally cost you throughput. The €180 weekend was the cheapest lesson we have had on this topic.

Working on a project where these methods apply?