When a task is large enough that it would exhaust a single context window, or when pieces of it can run simultaneously without interfering with each other, Claude Code can split the work across subagents. Each subagent is an independent Claude instance with its own context, its own working directory, and its own tool access. The orchestrator — the Claude Code session you are talking to — assigns tasks and assembles results.
This is not a niche capability. Subagents are how Claude Code handles codebase-wide migrations, parallel feature branches, large security audits, and test generation at scale. Understanding how the system works lets you design tasks that use it intentionally.
What Subagents Are
A subagent is a separate Claude agent instance running independently within a Claude Code session. The agent that spawns it is the orchestrator. The orchestrator assigns tasks; subagents execute them.
This is the same orchestrator/worker pattern you would use in any distributed system. The orchestrator holds the big picture — what needs to be done, in what order, and how results connect. Workers (subagents) know only their slice: the specific task they were given.
The Agent tool
Internally, Claude Code's orchestrator spawns subagents via an Agent tool call. The structure looks like this conceptually:
Tool: Agent
description: "Search all TypeScript files for usages of the deprecated getUserById function"
prompt: |
Search the codebase under src/ for every call to getUserById().
List each file path and line number where it appears.
Do not modify any files — only report findings.
Return a structured list: file path, line number, surrounding context (5 lines).
The subagent receives that prompt, executes with full access to the codebase's read tools, and returns its findings as the Agent tool result. The orchestrator receives the list and uses it to plan the next step.
You do not write this tool call yourself. Claude Code's orchestrator constructs it. But understanding the structure helps you write better instructions — because the prompt you give the orchestrator becomes the basis for the prompts it gives subagents.
What a subagent inherits vs what it does not
Inherits:
- The repository (read and write access to files in its working directory)
- CLAUDE.md from its working directory
- Any environment variables set in the session
- Tool permissions configured in settings.json
Does not inherit:
- The orchestrator's conversation history
- Context from other running subagents
- Any state that is not stored on disk or in the return value
This isolation is by design. It is what makes subagents safe to run in parallel — they cannot interfere with each other's reasoning because they share no in-memory state.
Why Subagents Matter
Parallelism
The most obvious benefit is speed. Two subagents working simultaneously on independent files finish in roughly half the wall-clock time of a single agent doing both sequentially. At ten subagents, the speedup is dramatic for tasks that genuinely parallelize.
Isolation
Each subagent has a clean context window. It does not carry the accumulated conversation history of the orchestrator. This is critical for large tasks — if you tried to do a 500-file analysis in a single context, you would either hit token limits or dilute the context to the point where quality degrades. Subagents keep each slice of the task focused.
Specialization
You can give different subagents different roles. One subagent might be a researcher — searching the codebase and producing a structured report. Another might be an implementer — given the research output, writing the actual code. A third might be a tester — given the implementation, writing tests for it. Each agent's prompt is optimized for its role.
Scale
For tasks too large for any single context window — a full codebase migration, a security audit across thousands of files, a complete API client rewrite — subagents are the only viable approach. The orchestrator decomposes the task into chunks, assigns each chunk to a subagent, and assembles the results.
How Claude Code's Subagent System Works
The execution cycle
- You give the orchestrator a task
- The orchestrator analyzes the task and identifies subtasks
- For each subtask, the orchestrator constructs an Agent tool call with a detailed prompt
- The subagent executes, using whatever tools it needs (Read, Write, Bash, Edit, etc.)
- The subagent returns its result to the orchestrator
- The orchestrator synthesizes results, checks for correctness, and either finalizes or spawns more subagents
For parallel tasks, steps 3–5 happen concurrently for multiple subagents.
How results come back
The subagent's entire output — everything it would say as a final response — becomes the Agent tool result that the orchestrator reads. This means the quality of subagent output directly affects orchestrator decisions. If you want the orchestrator to make good downstream choices, instruct it to ask subagents for structured, parseable output.
# Vague instruction to orchestrator
Find all the broken imports.
# Better — gives orchestrator language to use in subagent prompts
Find all broken imports. For each one, return: file path, line number, the broken import statement, and what the correct import path should be. Format as a JSON array.
The orchestrator will build subagent prompts that match this expectation, and the structured output will be reliably usable in the synthesis step.
Git Worktrees for Parallel Subagents
The critical infrastructure for parallel subagent workflows is git worktrees. Without worktrees, multiple subagents writing to the same files at the same time will overwrite each other's changes. With worktrees, each subagent works in an isolated directory on its own branch.
Why worktrees
A git worktree is a linked checkout of the same repository at a different path. Each worktree has its own working directory and can be on a different branch. Changes in one worktree do not affect others. This is exactly the isolation subagents need.
Creating worktrees for parallel subagents
Say you want three subagents to work on three independent modules simultaneously:
# From your main repository
git worktree add ../project-auth-work feature/auth-refactor
git worktree add ../project-api-work feature/api-refactor
git worktree add ../project-db-work feature/db-refactor
Now you have three directories, each on its own branch, each a full working copy of the repository. You can point a subagent at each one.
Running subagents in separate worktrees
When instructing Claude Code to use subagents for parallel work, specify the worktree path as the subagent's working directory:
Use three subagents working in parallel.
- Subagent 1: work in ../project-auth-work — refactor the authentication module to use JWT
- Subagent 2: work in ../project-api-work — add rate limiting middleware to all API routes
- Subagent 3: work in ../project-db-work — replace raw SQL queries with the ORM layer
Each subagent should only modify files in its own directory.
When all three finish, report what each one changed.
Merging results back
After all subagents complete, review each branch's diff before merging:
# Review each branch
git diff main..feature/auth-refactor
git diff main..feature/api-refactor
git diff main..feature/db-refactor
If a branch looks right:
git checkout main
git merge feature/auth-refactor
git merge feature/api-refactor
git merge feature/db-refactor
If there are merge conflicts (subagents touched the same shared file), resolve them manually. The conflicts will be limited to the files that genuinely overlap — not your entire codebase.
Discard a branch if the subagent produced bad output:
git worktree remove --force ../project-auth-work
git branch -D feature/auth-refactor
Designing Effective Subagent Workflows
When to parallelize vs serialize
Parallelize when:
- Subtasks work on different files and cannot block each other
- Subtasks are independent — the output of one is not the input of another
- Speed is the priority and you are willing to pay for more token consumption
Serialize when:
- Task B requires the output of Task A (research before implementation)
- Subtasks touch the same files and would create conflicts
- You need to validate each step before proceeding
Task decomposition for subagents
Good decomposition assigns each subagent a clear boundary. Bad decomposition assigns subagents overlapping responsibilities that require coordination.
Good decomposition for a codebase refactor:
Subagent 1: All files in src/components/ — update to new component API
Subagent 2: All files in src/hooks/ — update to new hooks API
Subagent 3: All files in src/utils/ — update to new utils API
Each subagent has a directory it owns. No overlap.
Bad decomposition:
Subagent 1: Update the button component and all places that use it
Subagent 2: Update the input component and all places that use it
The "all places that use it" parts will overlap — the same page file might use both Button and Input. Two subagents will try to edit the same file simultaneously.
How to write a subagent prompt from the orchestrator
The orchestrator's prompt to a subagent should contain:
- The task — precisely what to do
- The boundary — which files or directories to touch
- The constraints — what not to do (no new dependencies, no schema changes, etc.)
- The output format — what to return so the orchestrator can use it
- Relevant context — what the subagent needs to know that is not on disk
Task: Audit all TypeScript files in src/api/ for any function that makes
an HTTP request without error handling.
Boundary: Read only src/api/**/*.ts. Do not modify any files.
Constraints: Do not follow imports outside src/api/. Report only functions
that make fetch() or axios() calls without a try/catch or .catch() handler.
Output: Return a JSON array. Each element: { file, functionName, line, snippet }.
Context: We are preparing for a reliability audit. We need to identify every
unhandled HTTP call before we add global error handling middleware.
Passing context between orchestrator and subagent
The subagent cannot ask the orchestrator questions mid-task. Everything it needs must be in its initial prompt. This means the orchestrator must be explicit about context that is not obvious from reading the code.
For multi-step workflows where the output of one subagent feeds the next:
# Step 1: Research subagent
Ask: "Find all usages of the deprecated v1 API client. Return a list of
file paths and the specific lines to change."
# Orchestrator receives the list
# Step 2: Implementation subagent (receives the research output)
"Here is a list of files that use the deprecated v1 API client:
[research output from step 1]
For each file in this list, update the imports and calls to use the v2 API client.
The v2 client has the same method signatures but is imported from '@api/client/v2'.
Modify only the files in this list."
The orchestrator serves as the context relay — it takes the output of research agents and injects it into the prompts of implementation agents.
Common Subagent Patterns
Pattern 1: Research + Implementation
The most reliable pattern for tasks with ambiguous scope.
- Subagent 1 (Research): Reads the codebase, finds relevant files, understands the current implementation, and produces a structured report.
- Orchestrator: Reviews the report, forms an implementation plan.
- Subagent 2 (Implementation): Receives the plan and the research output, executes changes.
This pattern prevents the implementer from making assumptions about code it has not read. The research pass is cheap (read-only) and makes the implementation pass dramatically more accurate.
Pattern 2: Parallel Feature Development
For features that are truly independent:
Three features need to be implemented for the v2.0 release:
1. Dark mode toggle — UI only, affects src/components/ThemeProvider
2. Export to CSV — new utility in src/utils/export.ts + download button in Dashboard
3. Keyboard shortcuts — new hook in src/hooks/useKeyboard.ts + global listener
Use three parallel subagents, each in a separate worktree branch:
- feature/dark-mode
- feature/csv-export
- feature/keyboard-shortcuts
Implement all three simultaneously and report when done.
Pattern 3: Test Generation + Test Fixing Loop
A powerful pattern for coverage improvement:
- Subagent 1: Reads all source files in a module. Generates unit tests. Returns the test file.
- Subagent 2: Runs the test file and returns failures.
- Subagent 3: Receives the failures and fixes the tests (not the source, unless the source is actually wrong).
This loop can repeat until the test suite passes — each round uses fresh subagents with no accumulated confusion from previous failed attempts.
Pattern 4: Multi-File Refactoring at Scale
For a refactor touching hundreds of files:
We need to rename the function processUserInput() to sanitizeInput()
across 340 TypeScript files. This is a mechanical change — update the
function definition in src/utils/input.ts and update every call site.
Divide the work as follows:
- Subagent 1: src/components/ (87 files)
- Subagent 2: src/pages/ (112 files)
- Subagent 3: src/hooks/ (41 files)
- Subagent 4: src/api/ (100 files)
Each subagent handles a bounded slice. Because the change is mechanical (a rename), there is no risk of subagents making conflicting decisions — they are all doing the same transformation in different files.
Orchestrator CLAUDE.md vs Subagent CLAUDE.md
The orchestrator reads CLAUDE.md from the directory where Claude Code is launched. Subagents read CLAUDE.md from the directory they are working in.
In a single-worktree setup, all agents read the same CLAUDE.md — the one at the repository root. This is the common case and means your architectural constraints apply uniformly.
In a multi-worktree setup where subagents have their own directories, CLAUDE.md is read from each worktree's root. Since worktrees are clones of the same repository, they typically have the same CLAUDE.md. You can customize it per worktree if a particular subagent needs different constraints — but this is rarely necessary.
Configuring subagent behavior via CLAUDE.md:
## Subagent instructions
If you are working as a subagent (your task description mentions "subagent"):
- Return structured output (JSON or markdown tables) unless told otherwise
- Report what you changed, not just that you changed it
- If you encounter a file outside your assigned scope, do not touch it — report it to the caller
- Do not install dependencies without explicit instruction
Subagents will read this and apply the behavior, while human-driven sessions will generally not trigger the "if you are working as a subagent" condition.
Limits and Failure Modes
Context limits per subagent
Each subagent has the same context window as any Claude Code session — currently 200k tokens. For very large file reading tasks, a subagent can exhaust this. The symptom is truncated or incomplete output. Fix it by splitting the subagent's file scope further, or by using a research-first pass that identifies which files are actually relevant before reading them all.
What happens when a subagent fails
The orchestrator receives the failure as its tool result. In well-designed orchestrator prompts, you instruct the orchestrator to handle failures explicitly:
If a subagent reports a failure or returns an empty result, do not proceed
to the next step for that workstream. Report the failure to me with the
subagent's output so I can decide whether to retry or change approach.
Without explicit failure handling, the orchestrator might treat an empty result as "nothing to do" and silently skip work that actually failed.
Race conditions in shared state
The main risk of parallel subagents is editing the same file simultaneously. Using git worktrees eliminates this for file edits. For other shared state — a shared database, an external API, a file that multiple subagents need to update — you need to serialize those particular steps.
A common pattern: parallel subagents produce their changes as diffs or patch files rather than directly editing files. The orchestrator applies the patches sequentially, resolving any conflicts explicitly.
Cost tracking across subagents
Multiple parallel subagents run simultaneously, each consuming tokens. A workflow with ten subagents running in parallel can consume ten times the tokens of a single-agent workflow for the same wall-clock time.
To manage costs:
- Use research subagents (read-only, cheap) before implementation subagents (read+write, expensive)
- Scope each subagent's file access tightly so it does not read unnecessary files
- Prefer serialized subagent chains for tasks that are not time-sensitive
- Monitor your Anthropic Console usage dashboard after large workflows until you have a feel for per-workflow costs
Fleet Mode and Multi-Agent at Scale
Fleet mode is Claude Code's highest-scale multi-agent capability. Available in research preview for Max, Team, and Enterprise plans, it allows the orchestrator to dynamically spawn tens to hundreds of subagents in a single session.
Fleet mode is not something you configure — it is something you trigger by describing a task at the right scale:
Perform a full security audit of this codebase. Check every file in src/
for the following vulnerability classes: SQL injection, XSS, CSRF,
insecure direct object reference, and missing authentication checks.
There are approximately 800 files. Use as many parallel agents as needed
to complete this in one session. Return a structured report with findings
by file and severity.
Claude Code's orchestrator will decompose this into subagent batches, run them in parallel waves, collect findings, deduplicate, and assemble the final report.
The same pattern applies to codebase migrations at scale ("migrate all 1,200 files from CommonJS to ESM"), large test-writing sweeps, and dependency audits.
Real-World Example: Building a Full Feature with Subagents
Here is a concrete walkthrough of building a new feature — a user notification system — using a multi-agent workflow.
Starting point: You have a Next.js application with a database layer, API routes, and a React frontend.
Step 1: Research subagent
Use a subagent to analyze the codebase and answer these questions:
1. Where is the current user data model defined (schema + types)?
2. Are there any existing notification patterns we should follow?
3. Which API route files handle user-related operations?
4. What state management is the frontend using?
Return structured findings for each question.
The research subagent reads the codebase and returns a structured report with file paths, type definitions, and existing patterns.
Step 2: Plan based on research
With the research output in hand, you and the orchestrator agree on an implementation plan:
- Database: add
notificationstable with migration (1 subagent) - API: add
GET /api/notificationsandPOST /api/notifications/readroutes (1 subagent) - Frontend: add NotificationBell component and notification panel (1 subagent)
Step 3: Set up worktrees
git worktree add ../notif-db feature/notifications-db
git worktree add ../notif-api feature/notifications-api
git worktree add ../notif-ui feature/notifications-ui
Step 4: Run parallel implementation subagents
Use three parallel subagents, each in its assigned worktree:
Subagent 1 (../notif-db): Create the notifications table migration.
Schema: id, user_id, message, type (enum: info/warning/error), read (boolean),
created_at. Use the existing migration pattern in db/migrations/.
Subagent 2 (../notif-api): Add two routes in src/api/notifications/:
- GET /api/notifications — return unread notifications for the current user
- POST /api/notifications/:id/read — mark one notification as read
Follow the existing route pattern in src/api/users.ts.
Subagent 3 (../notif-ui): Add a NotificationBell component in src/components/.
Show unread count, click to open a dropdown panel listing notifications.
Use the existing Button and Dropdown components. Connect to the API routes above.
Do not start execution until all three subagent tasks are confirmed.
Step 5: Review diffs and merge
git diff main..feature/notifications-db
git diff main..feature/notifications-api
git diff main..feature/notifications-ui
Each diff covers exactly its module. No overlap. Review, test, and merge each branch.
Step 6: Integration test
After merging all three branches:
Run a subagent to write integration tests for the notification feature end-to-end:
test that creating a notification, fetching it, and marking it as read all work correctly.
Use the existing test patterns in tests/integration/.
The total wall-clock time for this workflow — with parallel subagents — is roughly the time of the single longest subagent task, not the sum of all three.
Summary
Subagents transform Claude Code from a single-threaded assistant into a multi-agent system capable of parallelism, isolation, and scale. The orchestrator holds the plan; subagents execute their assigned slices.
The key design decisions are:
- Decompose cleanly — assign each subagent a non-overlapping scope
- Use worktrees — give each subagent its own branch so parallel edits cannot conflict
- Be explicit about output format — structured output from subagents makes orchestrator synthesis reliable
- Handle failures explicitly — tell the orchestrator what to do when a subagent returns an error
- Match scale to the task — not everything needs parallel agents; serialize when tasks depend on each other
Start with single research+implementation pairs to get comfortable with the pattern, then build toward full parallel workstreams as you develop intuition for where the seams between tasks should be.