The three limit types
Every Nanny execution is governed by three independent limits. Any one of them can stop a run.Timeout
The wall-clock time limit in milliseconds. The moment the child process has been running fortimeout ms, Nanny kills it — regardless of what it’s doing.
Steps
The maximum number of agent steps allowed. Requires#[nanny::tool] (Rust) or @tool (Python) to report tool calls.
Cost
The maximum number of cost units the agent may spend. Each tool declares its cost per call; Nanny tracks the running total and stops the moment the budget is exhausted.Named limit sets
A singlenanny.toml can hold multiple limit sets for different workloads.
[limits] and override only the fields you declare.
In the example above, [limits.quick] inherits steps = 50 and cost = 500
from the base and only changes timeout.
Activate a named set at runtime:
What happens when a limit is hit
- Nanny kills the child process immediately — no grace period, no way for the agent to catch or delay the stop.
- An
ExecutionStoppedevent is emitted with the reason. - A human-readable message is printed to stderr:
nanny: stopped — TimeoutExpired. - Nanny exits with code
1.
| Reason | Trigger |
|---|---|
AgentCompleted | Process exited cleanly on its own |
TimeoutExpired | Wall-clock timeout exceeded |
MaxStepsReached | Step limit hit |
BudgetExhausted | Cost budget exhausted |
ToolDenied | Tool not in allowlist |
RuleDenied | Custom rule returned denial |
ManualStop | Stopped programmatically |
ProcessCrashed | Child process exited with non-zero code unexpectedly |