CCLearn

Subagent fan-out can cost more than one sequential session

Parallel subagent fan-out can cost more total tokens than doing the same work in one sequential session: each subagent pays for its own uncached system prompt and tool prefix, reloads the CLAUDE.md hierarchy and git status, and re-reads files its siblings already read.

docs corroborate

The official documentation describes the mechanism this relies on. The technique itself is community practice.

What this costs you if it is wrong

Denying the Agent tool trades tokens for context: exploration output that a subagent was absorbing lands in your main window instead, which on a large repo can cost more than it saves. The token magnitudes quoted in the community reports are individual anecdotes, not controlled measurements, and fan-out genuinely wins when research paths are independent and you care about wall-clock rather than spend. The orchestrator-cache-expiry mechanism as usually stated is wrong — the docs say the parent's prefix survives a subagent call — so do not avoid subagents for that reason.

You asked one question and watched Claude spawn a squad. Seven subagents, or twenty, each reading files, each burning through the window you were trying to protect. The window ends and nothing has landed. The instinct that got you here — parallel is faster, so parallel is better — is a wall-clock instinct applied to a token budget, and the two do not always point the same way.

Where the extra tokens come from

Three mechanisms, all documented, none of them stated as this conclusion.

Each subagent pays for its own prefix. Prompt caching is blunt about it: a subagent starts its own conversation with its own system prompt and tool set, and its first request does not read the parent's cache, because the two prefixes differ. It then warms a cache of its own across its turns — a cache that dies with it.

Each subagent reloads your project context. What loads at startup lists it: every level of the CLAUDE.md hierarchy the main conversation loads, a git status snapshot, and the full content of any preloaded skills. Explore and Plan skip CLAUDE.md and git status; every other built-in and custom subagent does not. A sequential run reads that material once. Ten custom subagents read it ten times.

Each subagent re-reads overlapping files. Nothing shares a read between siblings. Three agents investigating auth, database and API all open the same router, the same config, the same types file.

One mechanism you will hear that is wrong

The community version of this tip usually includes a fourth claim: while your subagents run, the orchestrator's own context ages out of cache, so you pay uncached rates for it again when they return.

The docs contradict the invalidation half of that. From the prompt caching page: the parent's cache is unaffected, and from the parent's side the subagent's call and result simply append to the conversation, leaving the parent's prefix intact. Spawning does not blow up your cache.

What survives of the claim is the clock. Cached prefixes expire on inactivity, and a parent waiting on a long fan-out is inactive. On API billing the main conversation gets five minutes, so a fan-out that runs longer than that does leave you re-processing the parent prefix. On a Claude subscription within your plan's included usage, the main conversation gets an hour, and almost no fan-out outlives that. Same symptom, different cause, and the fix is a TTL setting rather than avoiding subagents.

What the docs actually endorse

SituationDo thisDocumented at
Genuinely independent research pathsFan out — this is the supported patternsub-agents → Run parallel research
Sequential work, same-file edits, many dependenciesOne session, or subagents in a chainagent-teams → "a single session or subagents are more effective"
Verbose output you do not want in contextOne subagent, returning a summarysub-agents → Isolate high-volume operations
Large mechanical migration across files/batch, which splits across 5 to 30 worktree subagentsbest-practices → Fan out across files
You want exploration cheap againA project Explore agent with model: haikusub-agents → built-in subagents

That last row is the correction worth internalizing. "Subagents are cheap because Explore runs on Haiku" was true and is not. As of v2.1.198, Explore inherits the main conversation's model, capped at Opus on the Claude API. A user or project subagent named Explore overrides the built-in and keeps its own model field, so this restores the old behavior:

text
---
name: Explore
description: Fast read-only codebase search
model: haiku
tools: Read, Grep, Glob
---

Search the codebase and report only what was asked for, with file paths and line numbers. Do not edit anything.

To stop delegation entirely for a session that does not need it:

bash
claude -p "summarise the auth flow" --disallowedTools "Agent(Explore)"

Or persistently, in .claude/settings.json:

json
{
  "permissions": {
    "deny": ["Agent(Explore)"]
  }
}

The numbers you have heard are anecdotes

Reports of a single prompt fanning out to 7, 102, or 415 agents come from forum comments, not measurement. Treat the shape as real and the magnitudes as unverified — and note that since v2.1.217 a session refuses to spawn past 20 concurrent subagents by default (CLAUDE_CODE_MAX_CONCURRENT_SUBAGENTS), though there is no cap on the total over a session, and forks and resumes occupy or bypass those slots differently.

What is unverified here, and what would settle it

Nothing in the official docs says fan-out can cost more in total than the same work done sequentially. The docs supply every ingredient — separate prefixes, no shared cache on the first request, reloaded CLAUDE.md, agent teams using "significantly more tokens than a single session" at a cost "roughly proportional to team size", with the advice to keep teams small — and stop short of the arithmetic. No page in the corpus puts a multiplier on it. The closest they come is the agent-teams line that a single session is more effective for sequential or dependency-heavy work, which is an effectiveness claim, not a token one.

So this is a mechanism-corroborated inference, not a measured result. Nobody has published a controlled comparison. Run one yourself on a repo you care about:

bash
claude -p "summarise this repo" --output-format json | jq '.total_cost_usd'
claude -p "summarise this repo" --disallowedTools "Agent(Explore)" \
  --output-format json | jq '.total_cost_usd'

Run each three times and compare medians — one pair proves nothing, since delegation is a model decision that varies run to run. Note that total_cost_usd is a client-side estimate and can differ from your bill. If the denied-Agent run is reliably cheaper on your codebase, you have your answer for your codebase; if it is not, the tip does not apply to you.

Checkpoint

  1. A subagent starts and immediately reads three files your main session already read. Which of the three cost mechanisms is that, and which one is not happening at the same moment?
    Show answer

    That is the third mechanism: nothing shares a read between siblings, so overlapping files get opened again by every subagent that needs them. The other two are firing at that same moment — it started its own conversation with its own system prompt and tool set, whose first request cannot read the parent's cache because the prefixes differ, and unless it is Explore or Plan it also reloaded every level of the CLAUDE.md hierarchy plus a git status snapshot. What is not happening is the fourth mechanism the community version adds: the parent's cache is not being invalidated. From the parent's side the call and its result simply append, leaving its prefix intact.

  2. You are on a Claude subscription inside your plan's usage. A fan-out runs for eight minutes. Whose cache has expired — the parent's, the subagents', both, or neither?
    Show answer

    The subagents'. Subagents fall outside the main conversation's TTL bucket and get five minutes even on a subscription where your main thread gets an hour, so any child that idles longer than that between requests has already lost its own cache. The parent is fine: cached prefixes expire on inactivity, and eight minutes of waiting sits well inside its hour. Setting subagentPromptCacheTtl or CLAUDE_CODE_SUBAGENT_PROMPT_CACHE_TTL to 1h changes the child side, at a higher cache-write rate; both arrived in v2.1.242, so a settings file written before then is still handing every subagent five minutes without saying so.

  3. Your Explore calls got expensive after an upgrade. What changed, and what is the two-line fix?
    Show answer

    As of v2.1.198 Explore no longer always runs Haiku — it inherits the main conversation's model, capped at Opus on the Claude API — so delegation that used to be cheap now runs at whatever you are running. The fix is a user or project subagent that overrides the built-in: a file named Explore carrying name: Explore and model: haiku in its frontmatter, which keeps its own model field and restores the old behaviour. "Subagents are cheap because Explore runs on Haiku" was true and is not, which is the correction worth internalizing here.

Where this came from

Official pages that back this