IDInternals Decoded
Claude Code, Mastered
PlaybooksIntermediate11 min readJun 2026

Subagents and Parallel Work

Fan out research, reviews, and refactors to parallel agents without losing the plot.

Part 6 of 10Claude Code, MasteredView series →

Claude Code uses subagents to offload focused work from the primary agent loop. Each subagent is a short-lived agent with its own context, tools, and system prompt, dispatched as a tool call by the main agent. When multiple subagent calls are issued in a single turn, Claude Code runs them in parallel so research, reviews, and refactors complete in one coordinated step without flooding the primary agent’s token budget.

The surprising part: a single request can fan out a dozen subagents to check patterns across your entire codebase, merge their findings into a compact report, and return control to you before you finish your coffee. The key is context isolation and a strict response contract. Subagents do not dump raw file contents into the main conversation. They hand back distilled results that the primary agent uses for synthesis.

What is a subagent, and how is it different from a skill?

A subagent is a specialized agent loop defined in a .md file inside .claude/subagents/. It gets its own system prompt, its own tool access, and optionally its own model. A skill, by contrast, is a reusable block of natural language instructions that runs inside the main agent’s own thinking loop and shares its full context.

Before subagents, you taught Claude Code workflows through skills. That works well for multi-step procedures that need to see the whole project state. A subagent is better when the work is self-contained, heavy on token consumption, and only needs to return a terse result. The analogy: a skill is a function you inline; a subagent is a microservice you call.

Skills vs Subagents
Skills
  • Full project context
  • Sequential execution
  • Multi-step procedures
Subagents
  • Isolated context window
  • Parallel fan-out
  • Self-contained tasks
Skills share the full project context and run sequentially. Subagents get isolated context windows and can run in parallel for self-contained tasks.

Claude Code treats each subagent like a tool. When you define lint-reviewer.md or type-analyzer.md, the main agent sees them in its tool list and can invoke them by name, passing a description of the task as an argument. The subagent runs its own agent loop, reads files, executes tools, and finishes when it has produced the requested output. The main agent receives only the final response, not the full conversation trace.

How does Claude Code decide when to spawn subagents and coordinate them?

The primary agent loop handles planning. After you ask “Refactor the payment flow to use the new API (application programming interface) client,” Claude Code’s primary agent parses the task and decides which parts can be delegated. It consults the available subagents, their names and descriptions act as a menu of specialized workers. If you have defined a pattern-finder, a docs-checker, and a type-refactorer, the main agent can call all three in a single turn.

This delegation happens through the standard tool-calling mechanism. The model emits function calls like task(subagent="type-refactorer", description="Convert payment module return types to Result<T, Error>"). The Claude Code runtime then invokes the subagent, returns its output as a tool message, and the primary agent incorporates that result into the next planning step. When it calls multiple subagents at once, the runtime executes them concurrently before the primary agent thinks again.

Anthropic’s tool-use implementation supports parallel execution natively. The model can request several tool invocations in one message, and the client runs them together, collecting all results before the next model turn. Claude Code builds on this to treat subagent dispatches the same as any other tool call batch, so a single “fan out” step spawns all requested subagents simultaneously.

How does context isolation work, and how do subagents hand off useful results?

A subagent has an independent context window. It never sees the full conversation history or all project files at once. Instead, the subagent’s system prompt defines its role and the contract for its answer, while the main agent passes in only the relevant query and possibly pointers to shared artifacts like a plan file or memory bank. This isolation keeps the primary agent’s context clean: only the subagent’s final, distilled answer enters the main conversation.

The result of this isolation is that subagents must produce compact outputs. A good subagent prompt demands a specific format: a short summary, a list of file paths and line numbers, or a boolean success/failure plus a brief explanation. The primary agent can then merge these outputs into a coherent conclusion without wading through raw logs or full source dumps.

If you instruct the main agent to write a brief plan in a scratch file before fanning out, that file becomes a handoff artifact. The primary agent passes the file path to each subagent. The subagent reads the relevant sections, does its localized work, and returns findings anchored to the plan, not the entire codebase. This pattern makes subagents reliable even when many run in parallel.

How does parallel execution work under the hood?

Parallelism happens at the tool-call level. When the primary agent emits a message with three subagent invocations, the runtime calls all three concurrently. Claude Code’s runner uses an asynchronous loop that fires off each subagent and waits for all to finish. If one subagent takes longer, the others complete independently; the next primary agent step only begins after the last result arrives.

This execution model mirrors a fan-out/fan-in pattern. Map a batch of independent tasks to subagents, collect the results, and reduce them into a single decision. Under the hood, Claude Code’s parallelism has the same hazards as any concurrent system: if two subagents try to modify the same file simultaneously, the second write may overwrite the first. The primary agent is responsible for ordering mutations or using hooks to serialize writes.

Synchronization is implicit: the primary agent cannot proceed until all dispatched subagents return. There is no partial aggregation mid-step. If one subagent fails, its result includes an error flag that the primary agent can use to decide whether to abort or retry. This rigid step barrier keeps the system predictable even when you fan out to dozens of workers.

How do you design subagents for fan-out refactors and reviews on a real project?

Your side project’s payment module needs a migration to a typed result pattern. You define three subagents in .claude/subagents/:

  • type-refactorer.md, reads a file, rewrites function signatures to return Result<T, E>, and returns the list of changed files plus any compilation issues.
  • test-updater.md, scans test files, adjusts assertions to match the new result types, and returns a patch diff.
  • docs-validator.md, checks that every Result user has a docstring explaining the error variant and returns a checklist.

The CLAUDE.md for each subagent specifies its tool access (file read/write, linter) and its output format. The primary agent is instructed to first write a migration plan to a file, then call all three subagents in one message, passing the plan path as context. The primary agent then merges the results into a final commit message.

This fan-out reduces what would be a long, sequential chain of edits into a single concurrent step. The main agent never sees the raw diffs or every test file. It sees a summary like “5 files updated, 3 tests adjusted, 12 docstrings validated. Two failures: missing error docs in payment.ts line 42 and redundant import in types.ts.” That compact report lets it decide the next action without context bloat.

What breaks when you fan out too aggressively, and how do you recover?

The most common failure is the “thundering subagent” problem. If the primary agent fans out 20 subagents that all hit the same rate-limited API or drain your token budget rapidly, the runtime slows to a crawl or hits quota errors. Claude Code does not automatically throttle internal concurrency, so you must design subagent tasks that are truly independent and cheap to run, or set explicit concurrency limits via hooks.

Another risk is verbose subagent output defeating the purpose of isolation. If a subagent returns the full content of every file it touched, the primary agent’s context fills up fast. The fix is to refine the subagent’s prompt and output contract until it strictly returns only summary remarks and evidence pointers. You can also set a token limit in the subagent definition via the max_tokens field to enforce brevity.

Race conditions on shared state can occur if multiple subagents try to modify the same file or write to the same memory bank. Claude Code does not lock files across subagents, so you must sequence writes through the primary agent or use hooks to gate file access. If you spot inconsistent state after a parallel step, the primary agent can run a reconciliation pass: a dedicated subagent that reads all outputs and resolves conflicts in a deterministic order.

Quick Reference

PropertyValue
Subagent definition location.claude/subagents/*.md
Supported subagent modelsAny Claude model available via your plan
Parallel tool calls per turnEnabled by default (up to model limit)
Subagent context isolationEach subagent has independent context window
Handoff artifact patternPlan file, shared memory, or explicit passed context
Failure handlingSubagent returns error flag; primary decides retry/abort
Concurrency controlNo built-in limit; use hooks or project policy

Frequently Asked Questions

Q: When should I use a subagent instead of a skill? Use a subagent when a task is self-contained, token-heavy, and benefits from a separate context window and a terse result. Use a skill when the workflow needs continuous access to the full conversation and project state, like a multi-step deploy pipeline that builds on earlier outputs.

Q: Can one subagent call another subagent? No. Subagents in Claude Code are leaf workers invoked as tools. They operate independently and do not have access to the tool list that includes other subagents. If you need multi-step delegation, the primary agent runs a chain: spawn subagent A, inspect its result, then spawn subagent B with refined instructions.

Q: How many subagents can I run in parallel? The model limits the number of parallel tool calls per turn, and your token rate limits and quota govern how many concurrent LLM (large language model) calls the runtime can sustain. In practice, dispatching 3-6 subagents in one step is reliable. Pushing beyond 10 requires careful resource planning and possibly staggered fan-outs across multiple turns.

Q: What happens if a parallel subagent times out or fails? The subagent returns a result message indicating failure (for example, “Error: tool execution timed out”). The primary agent receives this alongside the successful results and can choose to retry the failing subagent with a different query, skip it, or abort the whole task.

Q: How do I keep shared state consistent across parallel subagents? The safest approach is to make subagents read-only or restrict them to writing to separate files. If they must modify shared state, have the primary agent sequence writes after the parallel read step, or use a hook to enforce a write lock so only one subagent touches a file at a time.

Test yourself

Your side project uses a shared types.ts file that defines core interfaces. Three subagents run in parallel: one refactors function signatures, one updates JSDoc types, and one migrates Redux action types. All three attempt to write updates to types.ts simultaneously. After the step, types.ts contains a garbled mix of changes from the second and third subagent, with the first’s edits missing.

Answer: The problem is a classic write-after-write race. Claude Code does not lock files across subagents, so the last writer wins. To recover, instruct the primary agent to spawn a reconciliation subagent that reads the current corrupted file and the intended outputs of all three workers, then merges them deterministically. For future runs, change the pattern: have the parallel subagents produce patch files or structured descriptions of their intended changes, and let the primary agent apply them sequentially after the fan-out step completes. You can also use a hook that serializes writes to that critical file, but that defeats parallelism. The better path is refactoring the subagent contracts so they target separate output artifacts that the primary agent merges.

If you want this kind of breakdown every week, how real systems actually work under the hood, subscribe to Internals Decoded at internalsdecoded.com. We unpack one internal mechanism per episode so you can design robust agentic workflows instead of crossing your fingers.

Sources

#subagents#parallel-agents
More from the library
The Newsletter

Keep up with AI. One email a week.

One thoughtful email each week. Unsubscribe whenever you like.