My Subagents Were Eating 48% of My Tokens. So I Gave Them Hard Budget Caps — Enforced by Hooks, Not Dashboards A developer built subagent-budget, an open-source Python tool that enforces per-agent-type token and dollar budgets for Claude Code subagents via PreToolUse hooks, blocking over-budget launches with exit code 2 instead of merely displaying spend. The tool was motivated by a widely circulated measurement showing subagents consumed 48.1% of tokens across 455 sessions, with a median subagent first request of 47,117 tokens. Budget rules are glob-matched against agent description and subagent type, persist across sessions in a JSONL ledger, and can import spend from the compatible resume-budget-guard tool. A few weeks ago a measurement made the rounds: developer aidiveyt logged a month of Claude Code usage — 455 sessions, 2,631 subagent runs — and found subagents had consumed 48.1% of all tokens . The median subagent's first request alone was 47,117 tokens. Nobody approved that spend. It just Task call at a time. Simon Willison's reaction was the whole community's reaction: "hard budget caps, please, now." I had the same problem and the same reaction. So I built subagent-budget : per-agent-type token and dollar budgets that are enforced by Claude Code hooks — an over-budget subagent is refused at launch, with the reason shown to the agent. A dashboard that can't stop a launch is a suggestion. This is a cap. pip install subagent-budget subagent-budget init --default-tokens 1000000 --default-usd 50 subagent-budget set-budget --pattern "Explore " --tokens 200000 --usd 10 subagent-budget sync backfill from ~/.claude/projects transcripts subagent-budget report Then the enforcement part — one block in ~/.claude/settings.json : { "hooks": { "PreToolUse": { "matcher": "Task", "hooks": { "type": "command", "command": "subagent-budget hook --event pre" } } } } Now every subagent launch goes through a budget check first. Under budget: it launches, and the hook prints the remaining headroom. Over budget: exit code 2 Claude Code's blocking-hook signal , and Claude sees exactly why: subagent-budget blocked launch of 'Explore auth code' Explore : token budget exceeded: used 210,441 / 200,000 tokens That last part is the whole point. Prompt-level instructions "please don't spawn too many subagents" don't survive contact with an agent mid-task. A hook that returns a non-zero exit sits below the prompt layer — the model can't argue with it, negotiate with it, or forget it. There's already a tool in this space — subagent-ledger — and it's honest about what it is: a display . It shows token counts, clears at session end, and can't stop anything. subagent-budget is built on the opposite premise: ~/.config/subagent-budget/ledger.jsonl and survives session ends. A budget that resets every session isn't a budget. Budget rules are globs matched against both the agent's description and its subagent type, first match wins — so Explore can have a tight shared pool while everything else falls back to the default. Either dimension can be left unlimited. If you already track spend across claude --resume with resume-budget-guard https://github.com/hahahahahahahahah6/resume-budget-guard , the ledger formats are deliberately compatible ts , kind , cost usd records . One command folds resume spend into the same caps: subagent-budget import-rbg imports ~/.resume-budget-guard/ledger.jsonl as agent "rbg: