Tool

Two limits, or one protection twice?

A hung call does zero iterations, so the counter freezes and can never fire. A spin does iterations and goes nowhere, so the clock only catches it at full cost. They guard opposite edges, and most systems have shipped two copies of the same half.

Your task's shape

A fuse has to sit above the tail of normal work, or it cuts off runs that were going to succeed. Take these from your traces rather than from intuition; the p99 is almost always further out than people expect.

min
min
$
$
s
Zero if a single call can block indefinitely.
x
Is the wall-clock deadline enforced outside the loop's execution?
A timeout checked at the top of the loop is not one: a hang never reaches the top of the loop.
This calculator runs entirely in your browser. Nothing you type is sent anywhere unless you ask for the result by email at the bottom of the page.
What each edge is guarded by
FailureWhat catches itAtStatus
Hang: nothing is happeningNothing catches itn/auncovered
Spin: iterations without progressIteration fuse60 passescovered
Slow tool callNothing bounds one calln/auncovered
Runaway spendIteration fuse and cost per pass$5within cap
Wall-clock deadline
27 min
Not enforced outside the loop
Iteration fuse
60
Set by the iteration tail
Worst-case spend
$5
The wall-clock deadline is not enforced outside the loop, so a hang never reaches the check that would end it.
With no tool-call timeout and no external deadline, a single hung call runs forever and no limit in the system can fire.
Neither fuse is looking at your task. Both are backstops: they bound the damage of a failure, they do not detect that the work is done. That still needs a measure of remaining work, and a fuse is a seat belt rather than a steering wheel.
Send me this analysis

Your numbers go with it. If the answer to the deadline question was no, that single gap is usually worth more attention than everything else on the page.

Your inputs are included so the reply can be specific.

What each fuse catches

Six ways a run goes wrong and which limit ends it. The two rows that matter most are the first and the last two: a hang is invisible to the counter, and nested work is invisible to both unless a budget is carried through every call.

FailureWall-clock deadlineIteration fuseNote
Tool call hangs indefinitelycatches itcannotcounter freezes, never fires
Loop spins without progresslatecatches itclock fires eventually, at full cost
One slow but returning callpartialcannotneeds a per-call timeout
Model requests tools forevercatches itcatches iteither one ends it
Nested agents multiply the workpartialcannotneeds a task-level budget
Task is impossiblecatches itcatches itboth fire, neither tells you why

Late means the clock ends it only after the full budget has been spent, which is protection against unbounded loss rather than against waste. Partial means it bounds the run but not the underlying cause.

A worked example

An agent with a 20-iteration cap and a 15-minute timeout. Two limits, both configured, and the team reports the loop as bounded on both axes.

The timeout is implemented as a check at the top of each iteration: if (elapsed > limit) break. It is correct, it is tested, and it has never failed to fire. It is also not a time fuse, because a hung tool call never returns, so the loop never reaches the top of the next iteration and the check is never evaluated. Both limits guard the spin edge, and the hang edge is uncovered.

There is no per-call timeout either, so a single call to a degraded dependency blocks the run indefinitely. Nothing in the system can end it: the counter has frozen, the timeout is unreachable, and the process sits there holding its resources until somebody notices.

The fix is small and it is not a tuning change. Move the deadline out of the loop, into something the loop cannot block, and add a per-call timeout so one dependency cannot take the run with it. The iteration cap can stay exactly as it is, because it was always guarding the other edge.

The arithmetic, so you can check it

The wall-clock deadline is p99 duration x margin. The iteration fuse is the smaller of p99 iterations x margin and spend cap / cost per iteration, and which of the two binds is worth knowing: if spend binds first, you are cutting off working runs to control cost.

The honest limit

Neither fuse is looking at your task. Both bound the damage of a failure; neither detects that the work is done. A run stopped by the hang fuse and a run stopped by the spin fuse are different diagnoses, and if they return the same thing to the caller you have thrown away the finding. The completion signal is a separate thing entirely, and it has to be a value computed in code from ground truth.

The full argument is in a time fuse and an iteration fuse are not the same thing. For what a tree of individually capped runs can spend, use the agent reliability calculator.

Questions

Should I use a timeout or a maximum retry count?

Both, because they guard opposite edges. A hung call does zero iterations, so the counter freezes and can never fire; only a clock catches that. A spin does iterations without making progress, and only the counter catches that. Two limits on the same edge is one protection with two names.

Why can't a max-iteration cap catch a hang?

Because the counter is incremented by the loop, and a hung loop is not looping. The count stops advancing at whatever it had reached and stays there, so the limit is never approached let alone crossed. This is why every embedded watchdog counts time rather than iterations and runs on its own oscillator.

Where does the wall-clock deadline have to be enforced?

Outside the loop's execution, by something the loop cannot block. A timeout checked at the top of each iteration is not a time fuse, because a hang never reaches the top of the next iteration. If the only thing that would end a hung run is a check inside the thing that is hung, there is no hang protection at all.

How high should the limits be set?

Above the tail of normal work, with margin, so they do not cut off runs that were going to succeed. Take the p99 from your own traces rather than from intuition, since it is almost always further out than people expect, then multiply. If a spend cap forces the iteration fuse below your p99, you are cutting off working runs to control cost, which is a legitimate choice worth making deliberately.

Do these fuses tell me the work is finished?

No, and that is the limit worth stating. Both are backstops that bound the damage of a failure. Neither looks at your task, so neither can distinguish a run that finished from one that ran out of budget. That still requires a measure of remaining work computed in code, and the two exits must be distinguishable to the caller.