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.
  • ProgrammaticallyGET /api/metrics exposes 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 01 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 maxBudgetUsd in 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.