Every team that ships an agent eventually adds a cost alert. Usually it is a budget alert on the provider console, a scheduled query over a billing export, or a dashboard threshold in an observability tool. These are useful tools. They are also structurally late, and the lateness is the whole problem when the spend comes from a loop.
The timing math
Take the coding agent loop we use as a reference case: 2,500 Claude Sonnet calls in 45 minutes, each carrying 150,000 input tokens and 2,000 output tokens. At list price each call costs 0.15 x $3.00 + 0.002 x $15.00 = $0.48. The loop fires about 56 calls a minute, so it burns roughly $26.67 a minute.
Now apply the latency of each alert type. A provider budget alert evaluates on the provider side and typically lands after usage has been aggregated. A billing export query runs on a schedule, often hourly or daily. A dashboard alert depends on metrics being emitted, scraped and evaluated over a window. Even an aggressive 15-minute detection delay lets this loop spend about $400 before anyone is paged, and paging is not stopping. The whole 45-minute loop costs $1,200.
Detection is not containment
Even a perfect alert only tells a human. Someone has to wake up, find the tenant, find the session, and kill a process or revoke a key. Revoking a key usually takes down every tenant that shares it. The realistic path from alert to containment at 2 a.m. is measured in tens of minutes.
An in-path control does not need a human for the first response. Because the gateway sees every request before it reaches the provider, it can refuse the next call. The decision happens on the request that would have spent the money, not on a report about money already spent.
What in-path detection looks like
PALM SOUQ evaluates four heuristics per agent session on every request: cyclical tool thrashing, token velocity surge, semantic echo loops, and max step or recursion depth. Each heuristic keeps a small rolling state in memory at the edge. When one trips, the gateway returns HTTP 429 with the header X-PalmSouq-Reason: circuit_breaker_triggered, and the agent framework sees an ordinary rate limit response it already knows how to handle.
In the reference loop, the same tool is called with the same arguments over and over. Tool thrashing detection trips after 15 identical calls, so the session spends 15 x $0.48 = $7.20 instead of $1,200. The decision itself takes under 50 ms.
HTTP/1.1 429 Too Many Requests
X-PalmSouq-Reason: circuit_breaker_triggered
X-PalmSouq-Heuristic: tool_thrashing
X-PalmSouq-Tenant: acme-legal
Retry-After: 0
{"error": {"type": "circuit_breaker_triggered", "session": "sess_8f2c", "calls": 15}}Keep the dashboards, move the control
None of this means you should delete your provider budget alerts or your billing export queries. They are the audit trail and the backstop. The point is that they answer a different question. Dashboards answer what happened. A gateway answers whether the next request should happen.
If your current setup can only tell you about a loop after it finished, the cheapest fix is to put the decision where the request is. Changing a base URL and passing a tenant header is usually a one-line change per client.
A checklist for your own stack
- Measure your real detection delay: trigger a harmless synthetic loop in staging and time how long until a human is notified.
- Multiply your worst per-minute agent spend by that delay. That number is your current uncapped exposure per incident.
- Decide what should happen automatically when a session misbehaves: refuse, degrade to a cheaper model, or pause and ask the user.
- Make sure the response your gateway returns is one your agent framework handles cleanly, so a breaker trip ends the session instead of triggering a retry storm.
Meera Krishnamurthy
CTO, PALM SOUQ
IISc (MTech, CDS). Built low-latency edge proxies at a CDN provider and rate-limiting infrastructure for a payments network handling 9,000 TPS. Owns the gateway and breaker engine.