Skip to content

Running 10 Agents at Once with herdr, Conductor and Worktrees

Running ten coding agents at once takes three layers: a git worktree per task so edits never collide, a supervisor that shows which agent needs you (Claude Code’s agent view, herdr, or Conductor), and a review queue that merges one verified pull request at a time. Worktrees isolate files only, so ports, databases and browser profiles need their own plan.

It is Friday afternoon and the backlog holds twelve small, independent issues. You open three terminals, start an agent in each, and go to a meeting. When you come back, one agent has sat on a permission prompt for 40 minutes, a second agent’s dev server quietly started on the next free port, and the third agent’s Playwright run passed against the second agent’s server. On Monday you have nine pull requests and no idea which of them were really tested.

This page is for the developer running a batch of agents, and for the tech lead making it repeatable for a team.

  • A launch recipe for three to ten agents in worktrees, with Claude Code, Codex and Cursor
  • The Worktrunk-plus-herdr example: three wt switch commands and one screen that shows who is blocked
  • A per-worktree plan for ports, databases, secrets and browser profiles
  • The workflow from issue batch to merge train, with three copy-paste prompts
  • The evidence each pull request carries before sign-off, and the failure modes to watch

The limit is not how many agents you can start but your review capacity, quota and machine.

  • Quota. Anthropic’s agent view documentation states that background sessions “consume your subscription usage the same as interactive sessions, so running ten agents in parallel uses quota roughly ten times as fast as running one” (code.claude.com, read 2026-09-26).
  • Disk and CPU. The Next.js repository’s conductor.json recommends "parallel_agents": 3 and notes “Each worktree uses ~500MB-1GB disk space after build” (vercel/next.js, canary, read 2026-09-26).
  • Review. Faros AI’s 2025 report found that developers on high-AI teams merge about 98% more pull requests while PR review time rises about 91% (secondary: search extract of faros.ai, read 2026-09-26). More agents move the bottleneck to review.
  • Measurement. METR wrote on 2026-02-24 that “our measurements of time-spent on each task are unreliable for the fraction of developers who use multiple AI agents concurrently.” Measure pull requests merged, reverted and time in review instead.
Agents at onceWhat worksWhere the limit shows
1–3Native worktrees and your terminal tabs, or Claude Code’s agent viewRemembering which tab is waiting
3–10A supervisor: herdr, cmux or a desktop app such as Conductor, plus per-worktree portsReview queue and quota
10+An orchestrator (Gas Town, CLI Agent Orchestrator), with dispatch paused when the review queue is fullMerge conflicts and reviewer load

Every tool below sits on the git worktree and adds a launcher, a state-aware terminal or a review GUI. Start with the built-ins; a third-party tool earns its place with mixed-agent fleets, state detection or a review board.

ToolLayerWhat it addsInstall (verified)Licence
Claude Code built-insWorktree + supervisor--worktree, .worktreeinclude, --bg, claude agents (agent view, research preview), --tmuxships with Claude Code 2.1.283vendor
Codex built-insWorktree + session list--worktree, codex agentsships with codex-cli 0.157.1vendor
CursorWorktree + cloudWorktrees, Cloud Agents in isolated VMsin the appvendor
Worktrunk (wt)Worktree launcherWorktree plus agent in one command; hooks; hash_portbrew install worktrunk && wt config shell installMIT or Apache-2.0
git gtr (CodeRabbit)Worktree launchergit gtr new … --ai, PR worktrees, cleanup of merged branchesbrew tap coderabbitai/tap && brew install git-gtrApache-2.0
herdrSupervisor terminalPanes marked working, blocked, idle, done or unknown; CLI and socket API; 24 agent kindsbrew install herdrApache-2.0
cmuxSupervisor terminal (macOS)Ghostty-based terminal, notification rings, cmux claude-teamsbrew tap manaflow-ai/cmux && brew install --cask cmuxGPL-3.0-or-later
Claude Squad (claude-squad)tmux + worktree TUIDiff view, commit and push per sessionbrew install claude-squad (for the short cs name, add the README’s symlink)AGPL-3.0
ccmanagerSession TUIBusy/waiting/idle state, .worktreeinclude, devcontainersnpm install -g ccmanagerMIT
ConductorDesktop app (macOS, closed)Claude Code and Codex in worktrees, one review boarddownload from conductor.buildproprietary
Gas Town (gt)OrchestratorA “Mayor” agent coordinating workers via Beadsbrew install gastownMIT
CLI Agent Orchestrator (cao)OrchestratorSupervisor and worker agents in tmux, web UIuv tool install git+https://github.com/awslabs/cli-agent-orchestrator.git@main --upgradeApache-2.0

Popularity as of 2026-09-26 (GitHub stars, read through the GitHub API for this site’s ecosystem dossier): herdr 40,779; cmux 27,412; Gas Town 18,195; Claude Squad 8,533; Worktrunk 8,416; git gtr 1,786; CLI Agent Orchestrator 1,350; ccmanager 1,250. Conductor is closed source and publishes no comparable metric. Stars measure attention, not fitness.

Start parallel agents with native worktrees

Section titled “Start parallel agents with native worktrees”

Each tool can put a session in its own worktree without extra software.

Start one session per issue, each in its own worktree. Claude Code creates the worktree under .claude/worktrees/<name>/ on a new branch named worktree-<name>:

Terminal window
# Terminal (repository root). One terminal per agent.
claude --worktree issue-101
claude --worktree issue-102 --tmux # same, inside a tmux session
claude --worktree "#1234" # worktree from pull request 1234

For more than three agents, dispatch them to the background and supervise from one screen; each background session moves into its own worktree before it edits files:

Terminal window
claude --bg --name issue-101 "Fix issue #101: pagination skips the last page. Add a failing test first."
claude --bg --name issue-102 "Fix issue #102: CSV export drops the header row. Add a failing test first."
claude agents # one screen: Ready for review, Needs input, Working, Completed
claude agents --json # the same state for scripts

Before the first run, add .claude/worktrees/ to .gitignore and create a .worktreeinclude in the repository root. It uses .gitignore syntax and copies only files that are both listed and gitignored:

.env
.env.local

Agent teams (experimental, CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1) suit one feature split among collaborating agents, not a batch of independent issues; the bundled /batch skill splits one large change into 5–30 worktree units.

Launch three agents with Worktrunk and watch them in herdr

Section titled “Launch three agents with Worktrunk and watch them in herdr”

Worktrunk creates the worktree and starts the agent in one command, and herdr shows every agent’s state in a sidebar. Both run on macOS and Linux.

  1. Install both tools and the herdr integration for your agent, which lets a restart restore the agent’s session:

    Terminal window
    brew install worktrunk && wt config shell install
    brew install herdr
    herdr integration install claude # also: codex, cursor, opencode, …

    On Windows, winget installs Worktrunk as git-wt because wt clashes with Windows Terminal, so run git-wt config shell install.

  2. Commit a project config so every new worktree gets its gitignored files, dependencies and its own dev-server port. pre-start steps block until they finish, so .env and node_modules exist before the agent starts; post-start runs in the background, which suits only the dev server. hash_port turns the branch name into a stable port between 10000 and 19999:

    .config/wt.toml
    [[pre-start]]
    copy = "wt step copy-ignored"
    [[pre-start]]
    install = "pnpm install"
    [post-start]
    server = "wt step tether -- pnpm dev --port {{ branch | hash_port }} --strictPort"
    [list]
    url = "http://localhost:{{ branch | hash_port }}"

    Worktrunk copies every gitignored file unless a .worktreeinclude (as in the Claude Code tab) limits it.

  3. Start herdr and create one workspace per agent, from the sidebar or with herdr workspace create --label feature-a. Run one line in each:

    Terminal window
    wt switch -c feature-a -x env -- 'PORT={{ branch | hash_port }}' claude 'Add user authentication'
    wt switch -c feature-b -x env -- 'PORT={{ branch | hash_port }}' claude 'Fix the pagination bug'
    wt switch -c feature-c -x env -- 'PORT={{ branch | hash_port }}' claude 'Write tests for the API'

    -c creates the branch and worktree, and -x runs one program after switching with the arguments after --. Worktrunk expands templates in those arguments, so env starts the agent with PORT set to the same hash_port value the dev server uses. The worker prompt and the Playwright config later on this page both read that PORT, so the agent’s tests hit its own server.

  4. Read the overview. herdr’s sidebar shows each agent’s state and rolls it up per workspace, so with one workspace per agent a blocked agent is visible without visiting each pane. For scripts, the CLI gives the same view; a manually launched agent has no name, so target it by the pane ID that agent list prints:

    Terminal window
    herdr agent list
    herdr agent wait w2:p1 --until blocked --timeout 600000
    herdr agent read w2:p1 --source recent-unwrapped --lines 80
  5. Merge each finished branch, one at a time. wt merge main squashes, rebases onto main, fast-forwards and removes the worktree; in a pull-request workflow, run gh pr create from the worktree and wt remove after the merge.

What you should see: three workspaces, each with Claude Code running in ../repo.feature-a, ../repo.feature-b or ../repo.feature-c; wt list shows three branches with three different ports in the URL column; each workspace’s sidebar state moves from working to idle or blocked as its agent progresses.

For a larger batch, script it. This loop was assembled from the herdr 0.9.1 CLI reference:

Terminal window
# Run from a shell inside herdr, at the repository root.
while IFS='|' read -r branch task; do
created=$(herdr workspace create --cwd "$PWD" --label "$branch" --no-focus)
pane=$(printf '%s\n' "$created" | jq -r '.result.root_pane.pane_id')
# task text must not contain single quotes
herdr pane run "$pane" "wt switch -c $branch -x env -- 'PORT={{ branch | hash_port }}' claude '$task'"
done <<'EOF'
issue-101|Fix issue #101 (pagination skips the last page). Write a failing test first.
issue-102|Fix issue #102 (CSV export drops the header row). Write a failing test first.
issue-103|Fix issue #103 (date filter ignores the time zone). Write a failing test first.
EOF

Conductor (Melty Labs) is a closed-source Mac app that runs Claude Code and Codex agents in parallel worktrees, with one board for reviewing them. Choose it for a GUI diff board on macOS; it does not run on Linux or Windows.

The verifiable part is the repository config. This is an abridged version of the conductor.json the Next.js repository commits (read 2026-09-26; the full file also has name, description, TURBO_TELEMETRY_DISABLED and a notes list):

{
"scripts": {
"setup": "./.conductor/scripts/setup.sh",
"run": "./.conductor/scripts/run.sh"
},
"worktree": { "default_branch": "canary" },
"environment": { "NEXT_TELEMETRY_DISABLED": "1" },
"recommendations": { "parallel_agents": 3 }
}

Give each worktree its own ports, database and browser

Section titled “Give each worktree its own ports, database and browser”

A worktree isolates files and the branch. Everything else is shared unless you split it, and most collisions are silent.

ResourceShared by default?What goes wrongFix
Files and branchNo—The worktree itself
Gitignored files (.env)Missing in the new worktreeTests fail on config, or the agent invents values.worktreeinclude (Claude Code, Worktrunk, ccmanager), wt step copy-ignored, gtr.copy.include
Dev-server portYesVite moves to the next free port unless strictPort is setA fixed port per worktree: hash_port, a port block per worktree index, or CONDUCTOR_PORT (secondary)
Test runner’s serverYesPlaywright’s reuseExistingServer attaches to whatever listens on the port, even another agent’s serverDerive baseURL, webServer.url and the dev-server port from one per-worktree value
Browser profileYesA persistent Playwright MCP profile can be used by only one browser at a timeStart Playwright MCP with --isolated in each agent
Local databaseYesTwo agents migrate the same schemaOne database per worktree (Worktrunk’s hash_port vars, a container per branch) or a sandbox
git config and the .git directoryYesA config write in one worktree changes all of themNever let an agent run git config; keep settings in committed files
Permission approvals (Claude Code)Yes“Don’t ask again” in one worktree applies to all of themPut deliberate rules in .claude/settings.json and review them
Production data, deploys, secrets, third-party APIsYesOne agent’s “quick check” writes live dataDeny the commands, and give agents sandbox credentials only

Tie the test runner to the same PORT the launcher gave the agent (the env prefix in the Worktrunk step), and fail loudly when it is missing instead of falling back to a shared default. For a Vite project with Playwright:

playwright.config.ts
import { defineConfig } from '@playwright/test';
// Locally, PORT comes from the agent's launch line; CI runs one server, so a default is safe there.
const port = process.env.PORT ?? (process.env.CI ? '5173' : '');
if (!port) throw new Error('PORT is not set: start the agent with its worktree port');
const baseURL = `http://localhost:${port}`;
export default defineConfig({
use: { baseURL },
webServer: {
command: `pnpm dev --port ${port} --strictPort`,
url: baseURL,
reuseExistingServer: !process.env.CI,
},
});

Give each agent its own browser for UI checks. The --isolated flag keeps the browser profile in memory, so parallel agents do not fight over one persistent profile. The commands are derived from the vendor’s install instructions for each tool:

Terminal window
claude mcp add playwright -- npx @playwright/mcp@latest --isolated

An MCP server’s tool schemas load into every agent’s context. Run /context in Claude Code before and after adding the server to see what it costs each of your ten sessions.

When file-level isolation is not enough (services, containers, networks), move each agent into a sandbox; the options are compared in agent sandboxes, and the full-stack pattern is in ephemeral environments per agent task.

Run the workflow from issue batch to merge train

Section titled “Run the workflow from issue batch to merge train”

The launcher is the easy half. What decides whether ten agents help is the work around them: a batch that does not collide, a standard prompt, supervision by exception, and a queue that merges one verified change at a time.

  1. Pick a batch that cannot collide. Choose independent issues with acceptance criteria, no two touching the same module. A read-only planning agent can triage.

  2. Create one worktree per issue, named after it (issue-101), so branch, pull request and agent row share one name.

  3. Dispatch with one standard prompt. Each agent writes a failing test, fixes the issue, runs the checks on its own port, and opens a draft pull request with the evidence.

  4. Supervise by exception. Watch only blocked or Needs input. Pause dispatch when the review queue reaches its cap; the review queue guide shows how to set it.

  5. Review evidence, not every line. A reviewer agent checks each diff against its acceptance criteria first (/code-review in Claude Code, codex review --base main in Codex). The human reads the test names, the evidence and the findings, and reads code where a finding or the risk level asks for it.

  6. Merge as a train. Merge one pull request at a time, rebase the next onto the new main, and re-run CI. GitHub’s merge queue does this for a team (add the merge_group event to the workflow that runs your required checks); wt merge main does it locally. When a rebase conflicts, re-dispatch the losing issue on a fresh worktree.

  7. Clean up. Remove merged worktrees: wt remove, git gtr clean --merged --closed, or claude rm <id> for a background session. Commit and push before you delete a session in agent view: deleting the session can remove the worktree Claude created for it (it is kept when it holds unpushed work unless you pass --discard-unpushed).

To start these agents from the issue tracker, see the issue-to-PR pipeline; to split one task among agents, see multi-agent orchestration patterns.

How do you know ten parallel pull requests are safe to merge?

Section titled “How do you know ten parallel pull requests are safe to merge?”

Each change has to prove itself without a human reading every line. Require four things per pull request, and let the merge queue enforce the last.

EvidenceProduced byChecked by
A test that fails without the change and passes with itThe worker agent, shown in the Evidence sectionReviewer agent (PASS on the first check)
Type check, lint and test suite run in the agent’s own worktree, on its own portThe worker agentCI on the pull request
A diff limited to the issue’s files, with no config, migration or lockfile changesThe worker agentReviewer agent, then a CODEOWNERS rule for the sensitive paths
Green CI on the head rebased onto the latest mainThe merge queueRequired status check

Sign-off stays with a person. The developer who dispatched the batch owns each merge. The tech lead owns the rules: batch size, the review-queue cap, which paths always need a human, and the numbers to watch (pull requests merged per day, time in review, reverts within a week). A rising revert count means the batch is too large or the criteria too thin; the fix is fewer agents, not faster review. For review bots that can take the first pass, see AI code review bots.

What breaks when you run ten agents at once?

Section titled “What breaks when you run ten agents at once?”

Tests pass against the wrong server. A dev server moved to the next free port and the test runner reused another agent’s server. Recovery: stop every dev server, pass each agent a fixed PORT with --strictPort, and re-run the tests of every pull request in that batch.

Two agents edit the same file. The second rebase conflicts. Recovery: merge the first and re-dispatch the second issue on a fresh worktree from the new main. Prevent it by listing expected files at triage.

A blocked agent goes unnoticed. herdr shows an unrecognized prompt as idle (unknown for Codex). Recovery: check anything idle or unknown for a few minutes with herdr agent read, or dispatch with claude --bg so the session lands in Needs input.

A worktree is missing .env or dependencies. Tests fail on configuration, or the agent writes placeholder values. Recovery: add the files to .worktreeinclude (or wt step copy-ignored), add the dependency install as a pre-start hook, and restart the agent.

The disk fills up. Next.js cites 500 MB to 1 GB per worktree. Recovery: git worktree list, then git worktree remove for merged work; run git worktree unlock first when git refuses a lock that Claude Code left on a -p run.

Work disappears. Deleting a session in agent view can remove its worktree (it is kept when it holds unpushed work unless you pass --discard-unpushed), and git worktree remove --force discards uncommitted work. Recovery: commit and push before you delete; if the branch is gone, git fsck --lost-found lists its commits until garbage collection.

The quota runs out mid-batch. Recovery: cap the batch, move routine issues to a cheaper model once your evals support it (see the models hub), and run long batches off-hours.

An agent touches shared state. A migration on the shared local database, a git config write or a production command affects every worktree. Recovery: restore from your backup, deny the command, and give agents sandbox credentials only. Keep Claude Code updated: its security advisories list a “Sandbox Escape via Git Worktree Path Confusion” rated High (2026-06-25).