automaintainer/ docs
Dashboard →

Budgets & spend caps

Set a daily spend cap and AM will stop starting autonomous runs for your account once the day's cost reaches it — so a scheduled fleet can't run up an unbounded bill overnight. It's the enforcement half of run costs: costs are measured per run, and the cap acts on the running total.

Set a daily spend cap

In Settings → Daily spend cap, enter a dollar amount (e.g. 5) and Save cap. 0 (empty) means unlimited — no cap.

The panel shows today's progress under the field — "Spent $1.20 of $5 today" — and a banner once the cap is reached.

What the cap does (and doesn't) block

When today's account spend reaches the cap, the scheduler stops dispatching autonomous runs (scheduled, explore, issue, PR-watch). It:

  • Pauses only autonomous runs. A run you start manually always proceeds — you're explicitly choosing to spend. Manual runs still count toward the total.
  • Auto-resumes at the next day boundary (00:00 Europe/Paris), the same day used for plan run limits.
  • Fails safe. If spend can't be computed, AM skips the run rather than risk going over.
scheduled run due → today's spend ≥ cap? → yes → skip (resume 00:00 Paris)
                                          └─ no → run as normal

Where the numbers come from

Spend is the sum of each run's reported cost (run costs) for the day. That data is produced on the worker by tokscale, so:

  • A worker without tokscale reports $0 — its runs cost nothing as far as the cap can see, so they won't trip it. Install tokscale on every worker you want the cap to account for — see Add a worker.
  • The figure is best-effort, not an invoice — treat the cap as a guardrail, not exact billing.

Per-model limits & fallbacks (advanced)

Below the spend cap, you can cap a specific model or provider by daily time (h/day) or cost ($/day) and set a fallback chain (e.g. opus → sonnet when exhausted). These shape which model a run uses; the account spend cap is the overall ceiling.

When a row sets both a time cap and a cost cap, whichever is hit first triggers the fallback.

The name and fallback fields autocomplete from the models and providers your connected workers actually report — start typing (partial matches like sonnet-4.6 resolve to claude-sonnet-4-6). A name that matches nothing on any connected harness is flagged as inert (it's stored but never matches). Use edit on an existing row to adjust its caps or fallback in place.