Cost & budget
How every Claude call is metered to a ledger, and how daily, monthly, per-cycle, and lifetime caps actually halt the autonomous loop.
Last updated
Because agents run unattended, cost is a first-class control input — not an
afterthought. Every claude call reports total_cost_usd, which is appended to
the cost ledger with running totals; budgets cap autonomous spend and actually
stop the loop when hit.
The ledger
Every agent run writes one line to logs/cost/ledger.jsonl — its tokens and USD —
with running totals kept overall, per-day, and per-month. Consultant
(sub-agent) cost rolls up to the agent that hired it; a delegated task’s cost
rolls up to its own assignee.
Money in has a ledger of its own: payments the org books via REVENUE[...]
land in logs/revenue/revenue.jsonl — see
Acting in the world for charging customers and
recording revenue.
Where you see it:
- Dashboard — the Status panel shows today’s and this month’s spend.
- Programmatically —
GET /api/metricsexposes the same numbers.
Unmetered spend is surfaced, not hidden. A brain that reports no price for a call (a local model, or a CLI whose output carries no cost) books as $0 in the money totals — correct for a free local model, but invisible to every cap. The ledger counts those calls and their tokens separately: the dashboard header flags them, and a budgeted org logs and audits a warning the first time one lands, so you know when the caps aren’t seeing everything.
Budgets
Budgets cap spend. There are four kinds; set any subset — an omitted field means no cap. An org booted with no cap at all prints a warning at start: budgets are the loop’s only hard brake, so running without one is a deliberate choice, not a default you fall into.
| cap | env var | behavior when hit |
|---|---|---|
totalUsd (lifetime) |
BUDGET_TOTAL_USD |
the org halts for good |
dailyUsd |
BUDGET_DAILY_USD |
skip cycles until the day rolls over |
monthlyUsd |
BUDGET_MONTHLY_USD |
skip cycles until the month rolls over |
perCycleUsd |
BUDGET_PER_CYCLE_USD |
logs a warning; halts new dispatch mid-cycle |
Budget is re-checked before each task and between drain passes, so a cap is real, not a start-of-cycle-only gate a single cycle could blow past.
Scoped budgets — caps per agent
An org-wide cap is a blunt instrument: one runaway agent can spend the whole
org’s budget before anyone else gets a turn. A budget key on an agent
scopes caps to that agent alone:
### Growth
- budget: { "dailyUsd": 3, "totalUsd": 25 }
A bare number means { "totalUsd": n }; the object takes dailyUsd,
monthlyUsd, totalUsd, and warnAt.
An agent past one of its caps is benched, not the org: it stops receiving
tasks and its open work moves to an in-budget colleague — like a firing —
while the rest of the org keeps running. A daily or monthly cap un-benches
itself when the period rolls over; a totalUsd cap is for good. If every
candidate is capped, the work simply defers to a later cycle rather than
blocking. Each of a budgeted agent’s sessions is also clamped to its remaining
headroom (via the same --max-budget-usd ceiling), so a single long run can’t
blow far through the cap either.
Warnings & incidents
Approaching a cap is a durable event, not a surprise. Crossing 80% of any
cap — org-wide or per-agent — writes one budget.warn event to the audit log;
an agent hitting its cap writes a budget.stop. Each fires once per scope per
cap period (a daily warning can fire again tomorrow, never twice today), so
budget pressure reaches you before the stop instead of being a silent halt
found in the logs later. Tune the fraction with warnAt (a 0–1 fraction
on any budget object) or the BUDGET_WARN_AT env var for the org.
The dashboard shows the same signals live: the roster panel has a budget column with each budgeted agent’s utilization of its most binding cap, and the agent drawer breaks spend down against each of its caps.
Setting a budget
Three places, in increasing precedence — a CLI flag beats an env var beats the file:
# in QUORUM.md
- budget: { "totalUsd": 50, "dailyUsd": 10, "monthlyUsd": 40, "perCycleUsd": 2 }
# environment
BUDGET_DAILY_USD=5 BUDGET_MONTHLY_USD=100 BUDGET_PER_CYCLE_USD=0.5 quorum
# CLI — the lifetime cap; halt for good at $25 spent
quorum --budget 25
A bare number as budget in a file means { "totalUsd": n }.
Per-session ceilings
Two more limits keep a single agentic run from blowing the cycle cap:
- The runtime reserves each task run a share of the remaining per-cycle
budget and passes it as the binary’s
--max-budget-usd. Concurrent sessions split the remainder rather than each being promised all of it, so even N runs dispatched at once cannot collectively exceed the cycle cap; a session’s unspent share is freed for later tasks the moment it settles. - A hired (or configured) agent can carry its own
maxBudgetUsdin its provider config as a standing per-run cap — a natural way to keep a junior role cheap.
### Engineer
- provider: { "type": "claude", "model": "claude-sonnet-5", "maxBudgetUsd": 2 }
A stop is immediate
When a hard cap is reached — or you stop the org — the current cycle’s work is
aborted immediately, killing in-flight claude children. Spend halts at
once, not at the next tick. See
the cycle.
Choosing a model and effort to control cost
The cheapest lever is the brain itself. Put a top model at high effort on the
roles that need judgment, and a cheaper model at lower effort on routine
execution — see The brain. Combined with maxBudgetUsd per
role and a lifetime --budget, you can let an org run unattended with a firm
ceiling on what it can ever cost.