Budgets and limits
Cap daily spend and tokens per project and across the host, and cap what one task may cost.
The Symphony spec retries failed work forever with backoff. With nobody watching, a broken credential or a task the agent can't finish becomes a steady drain of tokens. SI Fabrik's limits stop scheduling new work when money or retries run away. They never cut a turn short: running turns always finish.
Limits at a glance#
| Limit | Where | When it's hit |
|---|---|---|
limits.daily_budget_usd | WORKFLOW.md | The project starts no new attempts or continuation turns until midnight. Running turns finish. |
limits.daily_token_budget | WORKFLOW.md | The same, counted in tokens. |
limits.max_cost_per_issue_usd | WORKFLOW.md | The task is parked after its next failure. |
limits.max_attempts_per_issue (default 5) | WORKFLOW.md | After that many real failures in a row, the task is parked. Waiting for a free slot doesn't count. |
limits.pause_after_consecutive_failures (default 5) | WORKFLOW.md | After that many failures in a row across the project, the project pauses. |
| Max agents at once, daily budget, daily token budget | Mac: Settings → Limits. Server: limits: in harnessd.yaml | Host-wide: the same as the project limits, across all projects. |
claude.max_budget_usd | WORKFLOW.md | Claude Code itself stops one session that would cost more. |
Set any limit to 0 (or leave it out, for budgets) to keep the spec's behaviour.
Set project limits#
limits:
daily_budget_usd: 50 # this project, per day
daily_token_budget: 20000000
max_cost_per_issue_usd: 15 # across all attempts at one task
max_attempts_per_issue: 5 # failed attempts in a row before a task is parked (0 = forever)
pause_after_consecutive_failures: 5 # failures in a row across the project before it pauses (0 = never)Or use Workflow → Settings → Limits: Daily budget, Daily tokens, Cost cap per task, Park a task after and Pause the project after.
Set host-wide limits#
Open Settings → Limits. Under Across all projects, turn on and set:
- Max agents running at once (1–50);
- Daily budget (USD);
- Daily token budget.
The Today section shows what's been spent and how many tokens used, in total and per project.
limits:
max_concurrent_agents: 6
daily_budget_usd: 200 # dispatch stops for the day once reached (running turns finish)
daily_token_budget: 50000000An admin can also change them from the app in Server Settings → Limits; Use harnessd.yaml returns to the file's values.
How spend is counted#
- Spend and tokens come from each turn's usage, as reported by the runner, and include agents still running.
- Days are local calendar days; budgets reset at local midnight.
- Spend, per-task cost, parked tasks and automatic pauses are stored per project (
guardrails.jsonin its history folder) and kept across restarts.
When a budget blocks dispatch, the project header shows the reason, for example:
daily_budget_reached: this project spent $50.12 of its $50.00 daily budget (limits.daily_budget_usd). Dispatch resumes at midnight.
host_daily_budget_reached: all projects together spent $200.40 of the $200.00 daily budget. Dispatch resumes at midnight.Claude Code's cost estimate may not match what a LiteLLM proxy charges. With a gateway, give each project its own virtual key with a budget, and use LiteLLM's spend logs (tagged per project and task) as the source of truth.