Subagent Fleet Limits: Concurrency Caps & Nested Depth
On July 21, 2026 Claude Code shipped v2.1.217 and put the first hard caps on subagent fleets: 20 concurrent subagents per session, and nested spawning disabled outright. Three days later v2.1.219 (July 24) reinstated nesting at a default depth of 3. The trigger was public and specific: a June 13 issue where a single research task spawned 48+ simultaneous background agents and burned ~1.5M tokens on redundant work before the user could stop it (anthropics/claude-code#68110).
If you orchestrate more than a handful of agents per turn, these caps now shape what a single message can do — and how you write your .mcp.json, .env, and orchestration prompts.
- The four environment variables that govern fleets: concurrency, nesting depth, per-session total, and subagent model
- The exact error Claude sees when it hits the cap, and why the runtime tells it NOT to retry
- Why nesting was killed for 72 hours and what the restored default (depth 3) actually means for fan-out
- When ultracode exempts you from the concurrency ceiling, and when workflow hard caps override everything
- A parent-orchestrates pattern that stays inside the caps at any scale
The incident that shaped the caps
Issue #68110 (filed June 13, 2026) is the honest origin story. A user delegated a single research task to a general-purpose subagent. That subagent — because general-purpose subagents inherit the Agent tool — spawned its own children. Those children spawned more. Within a few turns, 48+ background agents were running, with four separate agents independently researching the same third-party API (Wise), and the user couldn't kill them faster than they respawned. Total spend before intervention: ~1.5M tokens.
The response arrived five weeks later in two shipping events:
| Date | Version | Change |
|---|---|---|
| 2026-07-21 | v2.1.217 | Concurrent cap = 20; nested spawning disabled (depth = 1) |
| 2026-07-24 | v2.1.219 | Nesting reinstated at default depth = 3 |
The three-day window with nesting off is the interesting bit — Anthropic clearly weighed "no fan-out" against "no orchestration" and picked a middle path.
The four environment variables
Every knob is a CLAUDE_CODE_ env var — set them in your shell, .env, or per-project via settings.json.
| Env var | Default | What it does |
|---|---|---|
CLAUDE_CODE_MAX_CONCURRENT_SUBAGENTS | 20 | Hard ceiling on subagents running at the same instant in one session. Hitting it fails the spawn with "Concurrent subagent limit reached". |
CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTH | 3 | How many levels deep a subagent can spawn its own children. 1 = disable nesting entirely (parent orchestrates only). |
CLAUDE_CODE_MAX_SUBAGENTS_PER_SESSION | 200 | Cumulative cap across the whole session — spawns beyond this fail even if concurrency is fine. |
CLAUDE_CODE_SUBAGENT_MODEL | (inherits) | Force every subagent onto a specific model. Route bulk stages to Haiku/Sonnet to keep an Opus budget on the parent. |
Two more numbers live inside the runtime, not env vars:
- Workflow hard caps for Dynamic Workflows & ultracode: 16 concurrent and 1,000 total agents per workflow run. These clamp anything a workflow launches, regardless of your session env.
- ultracode-active sessions are exempt from
CLAUDE_CODE_MAX_CONCURRENT_SUBAGENTS. The reasoning: ultracode's workflow layer already enforces its own 16/1,000 pair, so the session cap would double-book.
The error you'll actually see
When your main agent tries to spawn the 21st concurrent subagent (or the 4th nested one at default depth), the tool call returns:
Tool result — do not retry
Concurrent subagent limit reached
The runtime instructs the model not to loop against the cap — it should proceed with fewer agents or serialize. That's important for two reasons:
- Retrying is the exact behavior that made
#68110catastrophic. Backing off is by design. - If you see the same error in a hook or a log more than a few times in a row, you have a prompt problem, not a limits problem — your parent is fan-out-happy and needs to be told to batch.
How to configure a fleet
- Start at the default 20. Only raise it if you actually have independent work — a codebase-wide sweep across 60 packages, for example. Set `CLAUDE_CODE_MAX_CONCURRENT_SUBAGENTS=40` per project, not globally.
- Depth 3 (default) lets a parent → orchestrator → worker chain exist. Depth 1 forces you into a strict two-level topology: main session, and one layer of workers. Depth 1 is safer; depth 3 is more expressive.
- Set `CLAUDE_CODE_SUBAGENT_MODEL=claude-haiku-4-5` for a session where subagents do mechanical work. Your parent still runs on whatever `/model` you picked; only children downgrade.
- `CLAUDE_CODE_MAX_SUBAGENTS_PER_SESSION=200` is generous but real. A long day of `/agents` invocations can drain it. Restart the session to reset.
- The moment you catch yourself needing to raise the concurrency cap past ~40, you've outgrown one session. Delegate to a dynamic workflow — it gets the 16/1,000 workflow caps but also gets its own scheduler.
A parent-orchestrates pattern that survives the caps
The safest fleet topology under the new defaults is breadth-first from the parent — the main session spawns workers, workers do not spawn workers. This uses depth = 1 semantics even when depth = 3 is available, and it makes the concurrency math trivial: at any instant you have ≤ N workers, never a tree of unknown size.
Concrete shape for a 60-module codebase sweep:
Batch-orchestrated sweep — main session prompt
Sweep the codebase for uses of the deprecated `legacyClient()` helper. Batch the 60 packages into 3 waves of 20. For each wave: 1. Spawn 20 read-only `Explore` subagents in parallel, one per package. 2. Wait for all 20 to return before spawning the next wave. 3. Do NOT let a subagent spawn its own children — pass every package in the delegation prompt directly. Aggregate into a single `REPORT.md` after wave 3. Report the total count and any packages that failed with the exact error string.
Why this holds:
- 20 concurrent workers hits the default ceiling exactly once per wave — no failed spawns.
- Nesting is unused, so
CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTHdoesn't matter — the config works onv2.1.217(nesting off) andv2.1.219(nesting on). - Cumulative spawns: 60, well below the 200 per-session default.
When to break the pattern (and use nesting)
Depth = 3 exists for a reason: some problems really are hierarchical. Two shapes benefit from nesting:
- Deep research trees. A top-level
researchsubagent that itself needs to compare five sources — each one non-trivial — can spawn five siblingresearcherchildren. Depth = 2 total. - Map/reduce with per-shard finalize. Parent spawns N shard-owners; each shard-owner spawns 1 finalizer once its shard finishes. Depth = 2 total, but structurally cleaner than the parent tracking every finalize itself.
If either shape describes your work, leave the default alone. If your topology is flat, set CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTH=1 explicitly — it's a documentation and a safety net.
Interaction with /agents and background subagents
Two subtleties that trip people up when they first hit the caps:
- Background subagents count. Since Week 27 (June 29–July 3, 2026) subagents run in the background by default. A background agent still counts against your concurrency cap while it's running, even though the parent isn't blocked waiting for it.
background: truein frontmatter doesn't waive the cap. Pinning a subagent to background in its frontmatter changes when the parent resumes — not whether the runtime counts it.
If you're seeing the cap error and your main session feels idle, run /agents (or check the status line — see Statusline) to find what's still alive from earlier in the session.
Sonnet 5, Opus 5, and cost under the caps
The default CLAUDE_CODE_SUBAGENT_MODEL behavior is inherit — a subagent runs on whatever model the parent is on. For Opus 5 sessions with 20 concurrent workers, that adds up fast. The recommended shape after the caps landed is:
- Parent on Opus 5 for the orchestration and the final synthesis.
CLAUDE_CODE_SUBAGENT_MODEL=claude-sonnet-5for the workers doing well-scoped IO-heavy tasks.- For anything mechanical (grep-shape work, format checks), Haiku 4.5.
See Choosing a Model for the tier tradeoffs, and MCP Token Cost for how tool-heavy subagents inflate the bill regardless of model.
Check yourself
0/3- Default concurrent cap is 20; nesting depth default is 3 (was 1 for 72 hours in late July 2026).
- The four knobs are all `CLAUDE_CODE_*` env vars — concurrency, spawn depth, per-session total, and subagent model.
- 'Concurrent subagent limit reached' is a fail-and-stop signal, not a retry signal. Repeated occurrences mean your parent prompt is fan-out-happy.
- Parent-orchestrates-in-waves is the safest topology under the new caps and works identically on v2.1.217 and v2.1.219.
- If you need more than ~40 concurrent, you've outgrown one session — move to Dynamic Workflows and its 16/1,000 workflow caps.
Next
- Subagents & Parallel Agents — the primitive these caps constrain
- Dynamic Workflows & ultracode — the fleet-scale escape hatch
- Choosing a Model — pick a
CLAUDE_CODE_SUBAGENT_MODELthat matches the work - MCP Token Cost — why tool-heavy fleets still burn tokens even at cap
Sources & further reading
- Claude Code changelog — authoritative version history for
v2.1.217(2026-07-21) andv2.1.219(2026-07-24). - Create custom subagents — official docs for the primitive being capped.
- Week 27 · June 29 – July 3, 2026 — the "background by default" change that interacts with the concurrency cap.
anthropics/claude-code#68110— the exponential fan-out incident (48+ agents, ~1.5M tokens) that motivated the caps.anthropics/claude-code#78406— the community-filed doc gap for the per-session cap env var.- Claude Code v2.1.217 major updates — sub-agent limits and behavior — third-party writeup with the exact env-var names, published the day after
v2.1.217. - Claude Code Put Guardrails on Its Own Agent Fleets — practitioner analysis of the workflow 16/1,000 hard caps and the ultracode exemption.