Claude Code cost is token spend. Every request re-sends the conversation — mostly as cheap cache reads — plus whatever the model writes back, priced per model. You can watch it with /usage, and a scripted run can be stopped with --max-budget-usd. But the CLI reference marks that flag “print mode only”: an interactive session has no per-session dollar ceiling. Bulkhead adds one. Before every tool call its hook re-prices the session transcript, and once spend reaches your cap it refuses every further tool call until a human raises the number in bulkhead.yaml.
- $5default cap per session — yours to change
- $20default cap per day, per checkout
- -pthe only mode Claude Code’s own cap covers
npx @bulkheadtools/cli initWhat Claude Code costs, and where you see it
Anthropic’s cost guide puts the average at about $13 per developer per active day and $150–250 per developer per month across enterprise deployments, with 90% of users under $30 an active day. The spread comes from model choice, context size and how long sessions stay open. These tools report or limit that spend, and they do different jobs:
| Tool | What it does | Interactive | Stops the agent |
|---|---|---|---|
/usage | Shows the session’s token usage and a dollar estimate, computed locally at list price. | Yes | No — it reports |
--max-budget-usd | Stops a run once spend reaches the amount; subagent spend counts toward it. | No — print mode (-p) only | Yes |
| Org spend limits | Console workspace limits; usage-credit limits on Team and Enterprise plans. | Yes | Yes, at the org, workspace, group or member level — not per session |
| ccusage | Daily, monthly, per-session and five-hour-block reports from local usage data. | After the fact | No — it reports |
| Bulkhead | Per-session and per-day caps priced from the transcript; cost per prompt in bulkhead report. | Yes | Yes — denies every tool call at the cap |
How Bulkhead prices a session
Claude Code writes each session to a JSONL transcript, and its subagents get their own transcripts alongside it; every assistant message in any of them carries its model and token usage. On each PreToolUse and PostToolUse hook, Bulkhead reads the session transcript and its subagents’ and sums them — no estimate model, the same answer for the same files:
- Streamed messages are counted once: of the lines that share a message id, only the last — which carries the final count — is priced.
- Input and output tokens at the model’s list rate.
- Cache writes at 1.25× input for the five-minute cache and 2× for the one-hour cache (1.25× when the transcript doesn’t say which).
- Cache reads at 0.1× input, or the model’s own rate where it differs — an Opus 5.5 cache read costs $0.20 per million tokens, not $0.40 — except Mythos 5.1, priced at the default 0.1× (over-counts).
- A model id missing from the table is priced at Opus-tier rates, $5 in and $25 out per million, so an unknown model over-counts instead of slipping under the cap.
Bulkhead ships list prices for 14 model ids, matched exactly or by the longest prefix so date-suffixed ids resolve. Per million tokens:
| Model | Input | Output | Cache read | 5-min write | 1-hour write |
|---|---|---|---|---|---|
| claude-fable-5-1 | $10 | $50 | $0.25 | $12.50 | $20 |
| claude-fable-5 | $10 | $50 | $1 | $12.50 | $20 |
| claude-opus-5-5 | $4 | $20 | $0.20 | $5 | $8 |
| claude-opus-5 | $5 | $25 | $0.50 | $6.25 | $10 |
| claude-opus-4-8 | $5 | $25 | $0.50 | $6.25 | $10 |
| claude-opus-4-7 | $5 | $25 | $0.50 | $6.25 | $10 |
| claude-opus-4-6 | $5 | $25 | $0.50 | $6.25 | $10 |
| claude-opus-4-5 | $5 | $25 | $0.50 | $6.25 | $10 |
| claude-sonnet-5 | $2 | $10 | $0.20 | $2.50 | $4 |
| claude-sonnet-4-6 | $3 | $15 | $0.30 | $3.75 | $6 |
| claude-sonnet-4-5 | $3 | $15 | $0.30 | $3.75 | $6 |
| claude-haiku-4-5 | $1 | $5 | $0.10 | $1.25 | $2 |
Anthropic’s pricing page is the authority; the Mythos ids (limited availability) are in the file too. The table has one rate per model: fast mode’s premium and the 1.1× US data-residency multiplier aren’t applied, so sessions using either are under-counted. Override any model under budget.pricing.
Session and day caps
# Hard dollar caps. When crossed, every subsequent tool call is denied — the
# agent is effectively paused until a human raises the cap. Cost is a
# deterministic sum over the session transcript; no estimation model is used.
# Set to 0 to disable a cap.
budget:
session_usd: 5 # per Claude Code session
daily_usd: 20 # across all sessions today
# pricing: # optional per-model overrides (per 1M tokens)
# my-model: { inputPerMTok: 3, outputPerMTok: 15 }session_usd caps one Claude Code session. daily_usd caps the sum of every session run in this checkout on this machine on today’s local date (each clone and git worktree counts on its own); the running totals live in .bulkhead/spend/. When spend reaches a cap, the budget guard denies that tool call and every one after it. That is the pause: the agent can still answer in text, but it can’t act.
bulkhead demo: 19 turns like it, then one tool call. The hook checks at tool calls, so that is where the pause lands.What the agent reads when it tries its next tool call, and the one line you see, both from the demo:
⛔ Bulkhead blocked this action.
Guard: budget
Rule: session_usd=5
Why: Session spend $5.09 has reached the per-session cap of $5.00. Agent paused. Raise budget.session_usd in bulkhead.yaml to continue.
This is a deterministic policy check that runs outside the model and cannot be overridden by reasoning.
To proceed, a human must change bulkhead.yaml or perform this action manually.🛡 Bulkhead paused the agent: session spend $5.09 hit the $5.00 session cap — raise budget.session_usd in bulkhead.yaml to continue (ledger #55)The overshoot caveat
The cap is checked on every tool call, so one long model turn can overshoot before the next call is refused. In the demo the cap is $5.00 and the pause lands at $5.09: the last turn ran $0.09 past the cap before any tool call could be refused. A turn that ends in a text reply is added to the total when the agent stops, but nothing is refused until the next tool call. Set the cap a turn or two below the number you can’t exceed.
The agent can’t raise it with file tools or sed
bulkhead.yaml is on Bulkhead’s immutable protected-path list. The Edit/Write tools and the obvious shell edits (sed -i, redirects) are denied on it; a script or interpreter that writes the file isn’t — that gap is a job for a sandbox’s write rules, set up in Sandbox vs guardrails.
Per-prompt cost with bulkhead report
Every ledger entry records the session’s running total. bulkhead report takes the difference between consecutive entries and charges it to the prompt active at the later one — Claude Code sends hooks a prompt_id from v2.1.196 — then lists prompts most expensive first, with their tool calls and denials. On the session the home page’s receipt comes from:
$ bulkhead report 1
Session 7f2c1e…f3b91 2026-09-24T02:14 → 02:19
Cost: $1.01 across 1 prompt(s)
p-fix-…nding $ 1.01 8 tool call(s), 2 denied
Denied: 2
⛔ #6 Write · protected path (.env) (protected-paths)
⛔ #7 Bash · force-push to a protected branch (blocked-commands)
Evidence: file_modified×2, test_failed×1, test_passed×1, commit_created×1
Completion checks: (1 stop(s) blocked)
⛔ [tests-pass] contradicted: "All tests pass"
✅ [tests-pass] supported: "All tests pass"
✅ [committed] supported: "committed"bulkhead status shows today’s spend against the day cap, and bulkhead receipt prints spend against the cap on the receipt you paste into the PR.
ccusage and Bulkhead
ccusage is an MIT-licensed CLI that reads Claude Code’s local usage data and reports it by day, month, session and five-hour block — the quickest answer to “what did last month cost?”. Run npx ccusage@latest. It reports and doesn’t stop anything, by design. Bulkhead is the brake: a cap that pauses the agent mid-session, and a per-prompt breakdown kept in a ledger in your repo. They answer different questions and run fine side by side.
What the cap doesn’t do
- It isn’t your bill. It is a list-price sum of the token counts in the transcript; the Claude Console or your plan’s usage page is the authority.
- It only prices what reaches a transcript. Subagent spend is counted — Bulkhead sums their transcripts alongside the main session’s — but spend never written to one, such as the auto-mode classifier’s, isn’t in the sum.
- It stops tool calls, not tokens — see the overshoot caveat above.
- It works only while the hooks run.
--bareskips hooks, and bypass mode isn’t supported; for unattended runs read --dangerously-skip-permissions, honestly and auto mode vs deterministic rules. - For print-mode runs, keep
--max-budget-usdas well. It is the native cap there; the two run together.
Everything else Bulkhead enforces — blocked commands, protected paths, the claim check — is in the corpus you can run yourself, and Claude Code hooks for safety explains the hook events the cap rides on.
Claude Code cost: questions
Does --max-budget-usd work in interactive Claude Code?
No. Claude Code's CLI reference describes --max-budget-usd as “print mode only”: it caps runs started with -p. Interactive sessions have /usage to watch spend and organisation-level spend limits, but no per-session dollar cap. Bulkhead's budget.session_usd adds one through hooks.
How accurate is Bulkhead's dollar figure?
It is a deterministic sum of the token counts in the session transcript at list prices, cache reads and writes included, so the same transcript always gives the same number. It is not an invoice: fast-mode and data-residency pricing aren't applied, contracted rates aren't known, and unknown models are priced at Opus-tier rates on purpose. Override rates per model under budget.pricing.
I'm on a Pro or Max plan. Does a dollar cap mean anything?
Anthropic's docs note that on Pro and Max the session cost figure isn't relevant for billing, because usage is included in the plan. Bulkhead's cap works the same either way — it pauses the agent at a list-price amount — so on a subscription treat it as a usage limit per session and per day rather than a spend limit.
What happens when the agent hits the cap?
Every tool call it attempts is denied with a message that names the cap and how to raise it, and you see one line in your session. Raise budget.session_usd (or budget.daily_usd) in bulkhead.yaml to continue; the day cap also clears when the local date changes.
Should I use ccusage or Bulkhead?
Both, for different questions. ccusage reports what you spent — by day, month, session or five-hour block. Bulkhead enforces a ceiling while the agent runs and attributes cost to prompts in its ledger. Neither replaces the other.