Guides / Brain

Spend controls

How the brain caps what it spends on model calls, and how to raise or remove a cap.

Some brain commands call paid model APIs: enriching pages, embedding new content during sync, re-embedding code, onboarding fixes and brainstorming. Spend controls stop those commands from costing more than you expect.

There are three layers: a cap you pass to one run, cost gates that show an estimate and ask before spending, and a brain-wide spend posture that turns the gates into information only. Use this guide when a command refuses to run without a cap, or when you want to raise or remove one.

Time
10 minutes
For
Anyone running paid brain commands by hand, from cron, or from an agent

Before you start

  • A brain created with nexusbrain init.
  • A chat model or embedding model configured, since those are what cost money.

01How spend control works

A cap is a ceiling for one run, in US dollars. While the run is going, every model call is priced and added to a running total. If the next call would push the total over the cap, the run stops.

A cost gate runs before any spending. The command prints an estimate, and in an interactive terminal it asks you to confirm. In a script or agent, where nobody can answer, the command refuses or takes a safe fallback instead.

The spend posture is a brain-wide setting with two values. gated is the default and keeps every gate active. tokenmax means cost is not your constraint: gates print their estimate and continue, and runs with no cap go uncapped. Spend is still recorded either way.

  • An explicit number always wins. --max-usd 5 caps the run even when the posture is tokenmax.
  • Where a command accepts off, the words unlimited and none mean the same thing.
  • The spend.posture setting is separate from search.mode=tokenmax, which controls how much text search returns, not what it spends.

02Cap a single run

  1. Preview the run without spending.

    Most paid commands accept --dry-run, which lists the work and prints an estimate but makes no model calls.

    nexusbrain enrich --dry-run

    You should seeA list of candidate pages and a cost estimate. Nothing is written.

  2. Run with a cap.

    nexusbrain enrich --max-usd 5

    You should seeThe run proceeds and stops early if it would spend more than $5.

  3. Remove the cap for one run, if you mean to.

    nexusbrain enrich --max-usd off

    You should see--max-usd off: running uncapped, spend ledgered. followed by a link back to this page.

CommandCap flagDefaultAccepts off
nexusbrain enrich--max-usd (alias --max-cost-usd)$5Yes
nexusbrain onboard --auto--max-usdRequiredYes
nexusbrain reindex-code--max-cost (alias --max-cost-usd)No cap, confirmation gateYes
nexusbrain doctor --remediate--max-usd (alias --max-cost)No capNo
nexusbrain brainstorm and nexusbrain lsd--max-cost$5No
nexusbrain extract-conversation-facts--max-cost-usd$5No
nexusbrain syncNo cap flag. Uses the sync cost gate below$0.50 gate floorThrough config
Note

With nexusbrain enrich --workers above 1, the cap is best effort and can overshoot by about one in-flight call per worker. Use --workers 1 for an exact ceiling.

03Run paid commands from scripts and agents

Without a terminal, nobody can answer a confirmation prompt, so each command has a rule for what happens instead. Pass a cap, --yes, or set the posture to tokenmax to let them run.

  1. Give a scheduled onboarding run a cap.

    nexusbrain onboard --auto --max-usd 5

    You should seeThe onboarding fixes run and stop before spending more than $5.

CommandWithout a cap, `--yes` or `tokenmax`
nexusbrain onboard --autoRefuses with nexusbrain onboard --auto refuses without --max-usd N. and exits with code 2. This applies in a terminal too.
nexusbrain enrichRefuses with Refusing to spend without a cap in a non-interactive context. In a terminal it prints About to enrich up to ... with an estimate and exits with code 2.
nexusbrain reindex-codeRefuses and exits with code 2 without spending. Pass --yes or --max-cost off to proceed.
nexusbrain syncWhen the estimate is above the gate floor, imports your pages now and moves embedding into capped background jobs. Exits 0.
nexusbrain migrate embeddingsRefuses with Refusing to migrate without confirmation in a non-TTY environment. Re-run with --yes. even under tokenmax, because it rebuilds a column.

04Tune the sync cost gate

When nexusbrain sync embeds new content inline, it estimates the cost first. Below the floor it just runs. Above the floor it asks you in a terminal, and without a terminal it imports now and hands embedding to background backfill jobs, which have their own daily cap per source.

  1. Preview what a sync would cost.

    The cost preview runs for --all. It covers every registered source.

    nexusbrain sync --all --dry-run

    You should seeA line starting sync --all preview (inline embed): with a token estimate and an est. $ amount, or sync --all: embedding deferred to backfill jobs when embedding runs in the background. Then --dry-run: exit without syncing.

  2. Raise the floor if the prompt appears too often.

    nexusbrain config set sync.cost_gate_min_usd 5

    You should seeThe setting is saved. Syncs estimated at $5 or less no longer ask.

  3. Skip the gate for one sync.

    --yes embeds inline with no preview.

    nexusbrain sync --yes

    You should seeThe sync runs and embeds without a prompt.

SettingDefaultMeaning
sync.cost_gate_min_usd0.50Estimates at or below this run without asking. 0 asks on any nonzero cost. off never asks.
embed.backfill_max_usd_per_source_24h25Spending cap per source, per 24 hours, for background embed backfill jobs. off removes it.

05Set the spend posture

  1. Switch the posture to tokenmax.

    nexusbrain config set spend.posture tokenmax

    You should seeThe setting is saved. Paid commands now print lines such as spend.posture=tokenmax: proceeding (informational).

  2. Check the current value.

    nexusbrain config get spend.posture

    You should seeThe value, such as tokenmax. If the posture was never set, you see Config key not found: spend.posture, which means the default gated applies.

  3. Turn the gates back on.

    nexusbrain config set spend.posture gated

    You should seeCost gates and missing-cap refusals apply again.

Warning

Under tokenmax, commands that have no cap flag in their arguments run with no ceiling. Only use it on a brain whose API accounts have their own limits.

06See what was spent

Every priced model call made under a budget is written to a weekly audit file in ~/.nexusbrain/audit/, named budget-<year>-W<week>.jsonl, for example budget-2026-W38.jsonl. Set NEXUS_BRAIN_AUDIT_DIR to write these files somewhere else.

Each line is one JSON record. The event field is reserve before a call, record after it, reserve_denied when a call was blocked by the cap, or record_unpriced when the model has no pricing entry. record lines carry actual_cost_usd, the running cumulative_cost_usd, and the max_cost_usd cap that applied, with label naming the command or phase.

  1. Open this week of spend records.

    tail -n 20 ~/.nexusbrain/audit/budget-2026-W38.jsonl

    You should seeThe most recent records, one JSON object per line. Change the week number to match the file name in the folder.

07Troubleshooting

nexusbrain onboard --auto refuses without --max-usd N.

Add a cap, for example nexusbrain onboard --auto --max-usd 5, or pass --max-usd off to run uncapped.

Refusing to spend without a cap in a non-interactive context.

nexusbrain enrich was started from a script or agent. Add --max-usd with a number, or --max-usd off, --yes, or set spend.posture to tokenmax.

About to enrich up to 50 page(s) per source across 1 source(s), est. ~$... Re-run with --max-usd or --yes to confirm.

This is the preview gate in a terminal. Re-run with --max-usd to set a ceiling, or --yes to accept the default $5 cap.

A run stops with projected cost ... exceeds --max-cost or cumulative cost ... exceeded --max-cost.

The cap did its job. Re-run with a higher cap if the work is worth it. nexusbrain extract-conversation-facts prints Budget cap reached. Re-run with a higher --max-cost-usd to continue.

[remediate] est cost $... exceeds --max-usd $... Aborting.

The plan for nexusbrain doctor --remediate is estimated above your cap. Raise --max-usd, or run nexusbrain doctor --remediation-plan to see the steps first.

A scheduled sync prints Exceeds floor $0.5 in a non-interactive session and embeddings are missing afterwards.

The embeds were moved to capped backfill jobs. Run nexusbrain embed --stale to embed now, pass --yes to future syncs, or raise sync.cost_gate_min_usd.

[config] spend.posture must be 'gated' or 'tokenmax'

Only those two values are accepted. Check the spelling and run the config set command again.

reindex-code says requires a positive number in USD, or off/unlimited.

The value after --max-cost is missing, zero or not a number. Pass a positive amount such as --max-cost 2, or off.