Back to List

The Complete Guide to Claude Code Multi-Agent Parallelism: One Person, One Team

2026-03-16·10 min read·AITutorial

Introduction

In section four of my advanced guide, I covered multi-agent parallelism in about 40 lines. But after using it extensively, this capability runs much deeper than I initially described.

You've set up your CLAUDE.md, configured your Hooks, and mastered context management — the next question is: how do you get Claude to do multiple things at once?

One person operating multiple Claude instances in parallel can match the output of a small team. This post covers multi-agent parallelism thoroughly.


1. What Is Multi-Agent Parallelism

1.1 Core Concept

The idea is simple: break a large task into independent subtasks and let multiple Claude instances handle them simultaneously.

This isn't a new concept — software teams do it every day. The difference is that your "team members" are Claude instances, and the startup cost is nearly zero.

1.2 Three Modes

Claude Code offers three parallelism approaches, each suited to different scenarios:

ModeHow to StartContext IsolationBest For
Sub-agentsClaude creates automaticallyFully isolatedIndependent subtasks within a session
Multi-terminalOpen multiple terminals manuallyFully isolatedLarge cross-module tasks
Headless modeclaude -p commandFully isolatedBatch processing, CI/CD

1.3 Why Context Isolation Matters

Each Claude instance has its own context window. This means:

  • No interference — Terminal A reading 50 files won't affect Terminal B's context
  • Focused attention — Each instance only cares about its own task
  • Independent failure — One instance erroring out won't pollute another's context

Same principle as human team collaboration: everyone focuses on their module, then merge the results.


2. Plan Mode Deep Dive

2.1 Basic Usage

Press Shift+Tab twice to enter Plan Mode. In this mode, Claude analyzes without acting:

[Plan Mode] I want to add a bookmark feature to the blog
where users can save articles

Claude outputs:
1. Files and components to create
2. Storage approach (localStorage vs database)
3. UI interaction design
4. Existing files that need modification
5. Suggested implementation order

Press Shift+Tab once more to switch back to Act Mode, and Claude starts executing the plan.

2.2 When to Use Plan Mode

Not every task needs Plan Mode. This table helps you decide:

ScenarioPlan Mode?Why
Fix a clear bugNoGoal is clear, just fix it
Add a new featureYesMultiple files involved, plan first
Refactor a moduleYesNeed to understand dependencies
Change one config lineNoToo simple
Large cross-module changeStrongly yesEasy to miss things without a plan
Performance optimizationYesNeed to analyze bottlenecks first

2.3 Advanced Plan Mode Techniques

Technique 1: Use Plan output as a parallel task list

Plan Mode's greatest value isn't just "think before you act" — its output can directly serve as the task allocation plan for multi-terminal parallelism:

[Plan Mode] I want to add a daily check-in feature to a Flutter app

Claude's plan output:
├── Data layer: CheckIn model + Repository
├── Domain layer: CheckInCubit + state management
├── Presentation layer: CheckInPage + calendar widget + animations
└── Tests: unit tests + widget tests

→ These four parts can be assigned to four terminals

Technique 2: Specify constraints in Plan Mode

[Plan Mode] Add user authentication
Constraints:
- Use JWT, not sessions
- Passwords hashed with bcrypt
- Must support OAuth (Google, GitHub)
- Don't introduce a new database, use existing PostgreSQL

The more specific your constraints, the better the plan.

Technique 3: Plan Mode + CLAUDE.md synergy

If your CLAUDE.md defines architectural standards, Plan Mode will automatically follow them:

# CLAUDE.md
## Architecture Standards
- Use Clean Architecture (data/domain/presentation)
- State management: Bloc/Cubit only
- All Repositories must have interface definitions

Plan Mode will generate plans that conform to your architecture.


3. The Sub-Agent System

3.1 What Are Sub-Agents

When you give Claude an instruction containing multiple independent subtasks, Claude Code automatically creates sub-agents to handle them in parallel:

You: Do these three things simultaneously:
1. Add error handling to all API routes
2. Convert CSS variables from px to rem
3. Update the README's API documentation

Claude Code internally:
├── Main agent: coordinates and summarizes
├── Sub-agent 1: handles API error handling
├── Sub-agent 2: handles CSS unit conversion
└── Sub-agent 3: handles README update

3.2 Capabilities and Limitations

Can DoCannot Do
Read filesInteract with the user (can't ask questions)
Edit filesContext window is independent and smaller
Execute commandsCreate its own sub-agents
Search codeAccess the main agent's full context
Use Glob/GrepUse MCP tools

3.3 Context Sharing

The context relationship between main agent and sub-agents:

  • Main → Sub: Main agent passes task description and necessary context to sub-agents
  • Sub → Main: Sub-agent results are returned to the main agent
  • Sub ↔ Sub: Sub-agents are fully isolated from each other

This means: if two subtasks have dependencies, they're not suitable for sub-agent parallelism.

3.4 Triggering Sub-Agents

Claude doesn't always automatically create sub-agents. You can guide it:

# Explicitly request parallelism
"Please handle these tasks in parallel: ..."

# Emphasize independence
"These three tasks are independent and can run simultaneously: ..."

# Use numbered lists
"Do these things at the same time:
1. ...
2. ...
3. ..."

3.5 SubagentStop Hook

If you want to monitor sub-agent activity, use a Hook:

// .claude/settings.json
{
  "hooks": {
    "SubagentStop": [
      {
        "matcher": "",
        "hooks": [
          {
            "type": "command",
            "command": "echo 'Sub-agent completed: $CLAUDE_AGENT_ID'"
          }
        ]
      }
    ]
  }
}

This Hook fires when each sub-agent completes — useful for logging or post-checks.


4. Multi-Terminal Parallelism

4.1 Basic Setup

Multi-terminal parallelism is the most flexible and powerful approach:

# Terminal 1
cd my-project && claude
 
# Terminal 2
cd my-project && claude
 
# Terminal 3
cd my-project && claude

Each terminal is a fully independent Claude Code session with its own context window.

4.2 Task Splitting Strategy: By Module, Not by Step

This is the most important principle.

Wrong way to split (by step):

Terminal 1: Create database tables first
Terminal 2: Wait for Terminal 1, then write APIs
Terminal 3: Wait for Terminal 2, then build frontend

That's not parallelism — that's sequential execution.

Right way to split (by module):

Terminal 1: Data layer (model + repository + DB migration)
Terminal 2: Business layer (service/cubit + business logic)
Terminal 3: Presentation layer (UI components + pages)
Terminal 4: Tests (unit tests + integration tests)

The key: define interfaces between modules first (data structures, function signatures), then develop independently.

4.3 Coordination with --resume

--resume lets you pick up where you left off:

# List all sessions
claude --resume
 
# Resume a specific session
claude --resume <session-id>
 
# Name sessions for easy identification
claude --resume "frontend-refactor"

Practical workflow:

1. Terminal 1 finishes data layer → commits to feature branch
2. Terminal 2 needs type definitions → git pull to get latest code
3. Terminal 2 continues business layer development

4.4 Boris's Workflow (Expanded)

How Boris Cherny, creator of Claude Code, actually works:

Local terminals (2-3):
├── Terminal 1: Core feature development
├── Terminal 2: Testing and fixes
└── Terminal 3: Docs and configuration

Web sessions (claude.ai/code, 5-10):
├── Sessions 1-3: Independent feature modules
├── Sessions 4-5: Code review
└── Sessions 6+: Exploratory tasks (research, prototyping)

Key points:

  • Local terminals handle tasks requiring file system access
  • Web sessions handle analysis, review, and planning tasks
  • Use --resume to seamlessly switch between local and web

5. Headless Mode (claude -p)

5.1 Basic Usage

claude -p is non-interactive mode, designed for scripts and automation:

# Pass a prompt directly
claude -p "Analyze performance bottlenecks in src/lib/posts.ts and suggest optimizations"
 
# Pipe input
cat error.log | claude -p "Analyze these error logs and find the root cause"
 
# Specify output format
claude -p "List all unused dependencies" --output-format json

5.2 Batch Parallel Processing

The real power of Headless mode is batch parallelism:

# Review multiple files in parallel
for file in src/components/*.tsx; do
  claude -p "Review $file for code quality. Check:
  1. Performance issues
  2. Accessibility problems
  3. Project convention compliance" &
done
wait
echo "All reviews complete"
# Generate tests for multiple modules in parallel
modules=("auth" "posts" "comments" "search")
for module in "${modules[@]}"; do
  claude -p "Write unit tests for src/lib/$module.ts
  using vitest, covering all exported functions" \
  > "tests/$module.test.ts" &
done
wait

5.3 CI/CD Integration

# GitHub Actions example
- name: AI Code Review
  run: |
    claude -p "Review the changes in this PR:
    $(gh pr diff ${{ github.event.pull_request.number }})
 
    Focus on: security vulnerabilities, performance issues, code standards"

5.4 Limitations

  • No interactivity — can't ask you questions
  • Can't use Plan Mode
  • Every invocation starts with a fresh context (no history)
  • Best for well-defined, one-shot tasks

6. Practical Example 1: General Web Development

Scenario: Adding a "Bookmark" Feature to a Next.js Blog

Users can save articles, with bookmarks stored in localStorage.

Step 1: Plan with Plan Mode

[Plan Mode] Add a bookmark feature to the blog:
- Users can click a save button on article pages
- Bookmark data stored in localStorage
- Blog list page shows bookmark indicators
- New /bookmarks page displays all saved articles
- Must support i18n (Chinese/English)

Claude's plan:
├── 1. Data layer: hooks/useBookmarks.ts (localStorage CRUD)
├── 2. Components: BookmarkButton.tsx + BookmarkList.tsx
├── 3. Page: app/[locale]/bookmarks/page.tsx
├── 4. Integration: modify blog/[slug]/page.tsx and blog/page.tsx
├── 5. i18n: update messages/zh.json and en.json
└── 6. Tests: unit tests for useBookmarks hook

Step 2: Split Across Three Terminals

# Terminal 1: Data layer + Hook
claude "Implement the bookmark data layer:
1. Create hooks/useBookmarks.ts
   - addBookmark(slug: string)
   - removeBookmark(slug: string)
   - isBookmarked(slug: string): boolean
   - getBookmarks(): string[]
2. Store data in localStorage with key 'blog-bookmarks'
3. Write corresponding unit tests"
 
# Terminal 2: Components + Page
claude "Implement the bookmark UI layer:
1. Create components/BookmarkButton.tsx
   - Takes a slug prop
   - Toggles bookmark state on click
   - Shows filled star when bookmarked, outline when not
   - Needs aria-label
2. Create app/[locale]/bookmarks/page.tsx
   - Display all bookmarked articles
   - Empty state message
   - i18n support
Note: useBookmarks hook interface is:
{ addBookmark, removeBookmark, isBookmarked, getBookmarks }"
 
# Terminal 3: Integration + i18n
claude "Integrate bookmark feature into existing pages:
1. Add BookmarkButton next to article title in blog/[slug]/page.tsx
2. Add bookmark indicator to article cards in blog/page.tsx
3. Add bookmarks page link to Navigation.tsx
4. Update messages/zh.json and en.json with:
   - bookmarks.title: 'My Bookmarks'
   - bookmarks.empty: 'No bookmarked posts yet'
   - bookmarks.remove: 'Remove bookmark'
   - blog.bookmark: 'Bookmark'
   - blog.bookmarked: 'Bookmarked'"

Step 3: Merge and Verify

# After all terminals complete
npm run build    # Ensure compilation passes
npm run test     # Ensure tests pass

Key point: Terminals 2 and 3 both depend on the hook interface from Terminal 1, so we explicitly included the interface definition in their prompts. This way, even if Terminal 1 isn't done yet, Terminals 2 and 3 can develop against the agreed interface.


7. Practical Example 2: Flutter Development

Scenario: Adding a "Daily Check-In" Feature to a Flutter App

Users can check in once per day, consecutive check-ins earn rewards, and a calendar view shows check-in history.

Project Structure (Clean Architecture)

lib/
├── data/
│   ├── models/check_in_model.dart
│   └── repositories/check_in_repository_impl.dart
├── domain/
│   ├── entities/check_in.dart
│   ├── repositories/check_in_repository.dart
│   └── usecases/
│       ├── perform_check_in.dart
│       └── get_check_in_history.dart
├── presentation/
│   ├── cubits/check_in_cubit.dart
│   ├── pages/check_in_page.dart
│   └── widgets/
│       ├── check_in_calendar.dart
│       ├── check_in_button.dart
│       └── streak_badge.dart
└── test/
    ├── data/check_in_repository_test.dart
    ├── domain/perform_check_in_test.dart
    └── presentation/check_in_cubit_test.dart

Step 1: Define Interfaces in Plan Mode

[Plan Mode] Implement daily check-in feature (Clean Architecture):
- Users check in once per day, duplicate check-in shows already-checked-in message
- Calculate and display consecutive check-in streak
- Calendar view showing current month's check-in history
- Local storage (Hive/SharedPreferences)
- Bloc/Cubit state management

Please define all inter-layer interfaces first, no implementations.

The interface definitions from Plan Mode become the "contract" for each terminal.

Step 2: Four Terminals in Parallel

# Terminal 1: Data layer
claude "Implement check-in data layer (Flutter, Clean Architecture):
 
Interface definitions:
- CheckIn entity: { id, userId, date, streakCount }
- CheckInRepository interface:
  - Future<void> checkIn(String userId)
  - Future<List<CheckIn>> getHistory(String userId, DateTime month)
  - Future<int> getCurrentStreak(String userId)
  - Future<bool> hasCheckedInToday(String userId)
 
Implement:
1. data/models/check_in_model.dart (Hive TypeAdapter)
2. data/repositories/check_in_repository_impl.dart
3. Use Hive for local storage
 
Project uses Clean Architecture, follow existing Repository patterns."
 
# Terminal 2: Domain layer
claude "Implement check-in domain layer (Flutter, Clean Architecture):
 
Interface definitions (confirmed):
- CheckInRepository interface as above
 
Implement:
1. domain/entities/check_in.dart
2. domain/repositories/check_in_repository.dart (abstract class)
3. domain/usecases/perform_check_in.dart
4. domain/usecases/get_check_in_history.dart
 
UseCase rules:
- performCheckIn: check if already checked in today, throw if so
- getCheckInHistory: return check-in records for specified month
- getCurrentStreak: calculate consecutive days (reset on break)"
 
# Terminal 3: Presentation layer
claude "Implement check-in presentation layer (Flutter, Clean Architecture):
 
Dependency interfaces:
- CheckInCubit states: Initial, Loading, Loaded(history, streak, checkedInToday), Error
- CheckInCubit methods: checkIn(), loadHistory(month), loadStreak()
 
Implement:
1. presentation/cubits/check_in_cubit.dart + check_in_state.dart
2. presentation/pages/check_in_page.dart
3. presentation/widgets/check_in_calendar.dart (monthly view, highlight checked-in dates)
4. presentation/widgets/check_in_button.dart (grayed out when already checked in)
5. presentation/widgets/streak_badge.dart (flame icon + day count)
 
UI requirements:
- Calendar using TableCalendar or custom GridView
- Check-in button with animation feedback
- Streak badge with flame icon + count"
 
# Terminal 4: Tests
claude "Write tests for check-in feature (Flutter, Clean Architecture):
 
1. test/data/check_in_repository_test.dart
   - Test Hive storage CRUD
   - Test streak calculation
   - Test duplicate check-in rejection
 
2. test/domain/perform_check_in_test.dart
   - Mock Repository with Mockito
   - Test normal check-in flow
   - Test exception when already checked in
 
3. test/presentation/check_in_cubit_test.dart
   - Use bloc_test for state transitions
   - Test checkIn success/failure
   - Test loadHistory returns correct data
 
Use mocktail for mocking, bloc_test for Cubit tests."

Step 3: Integration

# After all terminals complete
flutter analyze    # Static analysis
flutter test       # Run tests
flutter run        # Run and verify

Flutter-Specific Parallelism Tips

  1. Define Entity and Repository interfaces first — This is the "contract" for all layers, must be settled before parallelizing
  2. Define Cubit/Bloc State classes upfront — Both presentation and test layers depend on them
  3. Use get_it for dependency injection — Develop layers independently, assemble in injection_container.dart at the end
  4. Widget tests can mock Cubits — No need to wait for the real business layer

8. Coordination Strategies

8.1 Merging Results

The biggest challenge with multi-terminal parallelism is merging. Recommended Git workflow:

# Main feature branch
git checkout -b feature/check-in
 
# Each terminal works on a sub-branch
# Terminal 1
git checkout -b feature/check-in-data
 
# Terminal 2
git checkout -b feature/check-in-domain
 
# Terminal 3
git checkout -b feature/check-in-ui
 
# Terminal 4
git checkout -b feature/check-in-tests
 
# Merge
git checkout feature/check-in
git merge feature/check-in-data
git merge feature/check-in-domain
git merge feature/check-in-ui
git merge feature/check-in-tests

8.2 Conflict Prevention

Conflicts happen when multiple terminals modify the same file. Prevention strategies:

  1. Define interfaces first — Settle all module interfaces in Plan Mode, commit shared files
  2. Assign by file — Each terminal owns different files, no overlap
  3. Modify shared files last — Files like pubspec.yaml or injection_container.dart that everyone needs to touch should be handled by one terminal at the end
  4. Type definitions go first — Commit type/interface files first, other terminals pull before starting

8.3 Communication Protocol

Terminals can't communicate directly, but can coordinate through the file system:

# Terminal 1 signals completion
echo "data layer done" > .claude/signals/data-ready
 
# Terminal 2 can check
cat .claude/signals/data-ready

In practice, the simplest approach is still: Git commits + pull.


9. Best Practices and Anti-Patterns

9.1 Best Practices

  1. Plan Mode first — Always plan before opening multiple terminals
  2. Interfaces before implementation — Define module boundaries, then parallelize
  3. Split by module, not by step — Horizontal slicing, not vertical
  4. Give each terminal clear context — Include interface definitions and constraints in prompts
  5. Unified CLAUDE.md — All terminals share the same CLAUDE.md for consistent code style
  6. Small commits — Each terminal commits after completing a small feature, making it easy for others to pull
  7. Use --resume for continuity — Resume after interruptions instead of starting over
  8. Headless for batch tasks — Code reviews, test generation, and other repetitive tasks use claude -p

9.2 Anti-Patterns

Anti-PatternProblemCorrect Approach
Opening terminals without planningTask overlap, frequent conflictsPlan Mode first, then assign
Splitting by stepsBecomes sequential, loses parallelismSplit by module
Parallelizing without defining interfacesInterface mismatches at merge timeDefine interfaces first
All terminals editing the same fileMerge conflict hellAssign file ownership
Overloading one terminalContext explosion, quality drops1-2 focused tasks per terminal
Skipping CLAUDE.mdInconsistent code style across terminalsUnified CLAUDE.md
Ignoring HooksManual lint/format/test in every terminalConfigure Hooks for automation
Switching terminals without committingOther terminals can't see latest codeSmall commits, frequent pulls

10. FAQ

Q1: What's the difference between sub-agents and multi-terminal?

Sub-agents are automatically created by Claude within a single session — you don't manage them. Multi-terminal means you manually open multiple Claude Code instances. Sub-agents are good for small parallel tasks; multi-terminal is for large cross-module work.

Q2: Will multiple terminals interfere with each other?

No. Each terminal has a completely independent context window. The only "intersection" is the file system — if two terminals modify the same file simultaneously, you'll get conflicts. That's why you split by module.

Q3: Can Headless mode use MCP tools?

Yes. claude -p supports MCP tools, but they need to be configured in advance.

Q4: Does Plan Mode output consume context?

Yes. Plan Mode output occupies context just like regular conversation. If the plan is long, use /compact after confirming it.

Q5: How many terminals can I run in parallel?

No hard limit — depends on your machine's performance and API quota. In practice, 3-5 terminals is a comfortable range. Beyond 5, coordination overhead starts to increase.

Q6: What happens if a sub-agent fails?

The main agent receives the sub-agent's error and usually retries or adjusts its strategy automatically. If it keeps failing, the main agent takes the task back and handles it directly.

Q7: Can I use multi-terminal parallelism in CI/CD?

Yes, using Headless mode with shell background jobs:

# Parallel Claude tasks in CI
claude -p "Review for security vulnerabilities" > security-review.md &
claude -p "Check for performance issues" > perf-review.md &
claude -p "Verify API compatibility" > api-review.md &
wait

Conclusion

Multi-agent parallelism is one of Claude Code's most powerful capabilities. The core workflow:

  1. Plan Mode → Define tasks and interfaces
  2. Split by module → Assign to multiple terminals
  3. Parallel development → Each works independently
  4. Merge and verify → Git merge + tests

Master this workflow, and one person really can match a small team.


Recommended Reading