# How I Run 4 Claude Code Agents in Parallel on One Repo Without Chaos

> Source: <https://dev.to/yureki_lab/how-i-run-4-claude-code-agents-in-parallel-on-one-repo-without-chaos-5ejc>
> Published: 2026-09-11 14:32:06+00:00

I run up to four Claude Code agents at the same time on a single repository by giving each one its own git worktree, a tightly scoped task, and a merge queue at the end. Done right, parallel agents turned a week of sequential refactoring into an afternoon. Done wrong (I did it wrong first), you get four agents editing the same file and a merge disaster that eats every minute you "saved." Here's the setup, the failure modes, and the rules I follow now. 🚀

One Claude Code session is great. But last quarter I stared at a backlog that was embarrassingly parallel:

None of these tasks depended on each other. Running them one at a time through a single agent session meant babysitting my terminal for days, mostly watching an agent do work that didn't need my attention.

The obvious idea: run four agents at once. The obvious problem: they'd all be working in the **same working directory**. Two agents running `npm test` simultaneously clobber each other's build artifacts. Two agents editing neighboring lines of the same barrel file produce garbage. One agent runs `git checkout` mid-task and yanks the floor out from under the other three.

My first naive attempt — four terminal tabs, same directory, "they probably won't collide" — lasted 40 minutes before agent #2 committed agent #3's half-finished changes along with its own. I reverted everything and started over with an actual design.

The fix has three parts: **isolation** (git worktrees), **decomposition** (non-overlapping task contracts), and **integration** (a serial merge queue). I'm on Claude Code v2.x and git 2.44 here, but nothing below is version-sensitive.

Git worktrees are the underrated feature that makes this whole thing work. A worktree is a second (third, fourth...) checkout of the same repository that shares one object database but has its own working directory, its own index, and its own checked-out branch:

```
# From the main checkout
git worktree add ../repo-agent-1 -b agent/validation-migration
git worktree add ../repo-agent-2 -b agent/jsdoc-pass
git worktree add ../repo-agent-3 -b agent/logging-swap
git worktree add ../repo-agent-4 -b agent/characterization-tests
```

Now each agent gets launched with its **own directory as the working root**:

```
cd ../repo-agent-1 && claude "Migrate the API handlers in src/api/ to zod validation. Task spec is in TASK.md."
```

Each agent can run tests, install dependencies, create commits, even make a mess — and the other three never see it. No shared index, no shared working tree, no `git checkout` rug-pulls. The failure mode from my naive attempt is structurally impossible.

Two practical notes that bit me:

`node_modules`. Either let each agent install its own (slow, safe) or symlink from the main checkout (fast, occasionally cursed when an agent modifies a lockfile). I install fresh. The 90 seconds of `npm ci` per worktree is nothing next to debugging a shared-`PORT=3001`, `PORT=3002`, ...) and a scratch database name in its task spec.
Isolation stops agents from stepping on each other's *working directories*, but it doesn't stop them from editing the *same logical files* — which just moves the collision from runtime to merge time. Way better, still bad.

So every parallel task gets a short **task contract** — a `TASK.md` dropped into the worktree before the agent starts:

```
# Task: Replace deprecated log.info() calls

## You own (may edit):
- src/**/*.ts EXCEPT src/api/** and src/shared/logger/**

## You must NOT touch:
- src/api/**            (owned by agent-1 this session)
- package.json, any lockfile
- CI config

## Definition of done:
- `grep -r "log.info(" src` returns 0 hits outside src/api
- `npm test` passes
- Work is committed on this branch with a descriptive message
```

The load-bearing part is the **ownership map**. Before launching anything, I spend ten minutes deciding which agent owns which paths, and the union must be disjoint. If two tasks genuinely need the same file, they don't run in parallel — one of them waits. That sounds obvious written down; it took a mangled merge for me to actually start doing it.

Shared "junction" files (barrel exports, route tables, config) deserve special paranoia. My rule: **no agent touches a junction file during a parallel session.** If a task needs a new export added to an index file, the agent leaves a note in its final commit message and I do the two-line edit myself during integration.

Parallel work, serial integration. When agents finish, I never merge branches simultaneously or in arbitrary order. The flow is:

``` php
graph LR
    A[agent/validation] --> Q{merge queue}
    B[agent/jsdoc] --> Q
    C[agent/logging] --> Q
    D[agent/tests] --> Q
    Q -->|one at a time| I[integration branch]
    I -->|full CI green| M[main]
```

Concretely:

`integration` branch, run the full test suite.`main` only ever receives Step 3 matters more than it looks. Each agent validated its work against the repo *as it was when the session started*. After the first merge, that assumption is stale. The rebase-and-recheck catches interactions — like the validation migration changing an error message format that the new characterization tests had snapshotted. If the ownership map was truly disjoint, rebases are conflict-free and this whole phase is 20 minutes of watching CI. When it's not conflict-free, that's a signal my decomposition was wrong, and I treat it as a lesson for next session's ownership map, not as a merge problem to power through.

My end-to-end loop for a four-agent afternoon:

```
# 1. Decompose: write four TASK.md files, check ownership is disjoint
# 2. Spin up worktrees + branches (script does this in ~10s)
./scripts/spawn-worktrees.sh validation jsdoc logging tests

# 3. Launch agents, one terminal tab each, non-interactively
cd ../repo-validation && claude -p "$(cat TASK.md)" &

# 4. Check in every ~20 min; answer questions, unstick anyone stuck
# 5. Integration: merge queue, one branch at a time
# 6. Tear down
git worktree remove ../repo-validation  # etc.
git worktree prune
```

While agents run, I do interrupt-driven supervision instead of continuous babysitting: glance at each tab, unstick whoever's stuck, and otherwise do my own work. Four tasks that would have serialized into roughly four days of elapsed time landed in `main` the same evening.

**Parallelism amplifies your decomposition skills — in both directions.** With a clean ownership map, four agents ≈ 3.5x throughput. With a sloppy one, four agents produce merge conflicts faster than one agent produces code. The ten minutes of upfront path-ownership planning is the highest-leverage ten minutes of the whole session.

**Worktrees beat clones, and both beat shared directories.** Full `git clone` s per agent also work but waste disk and drift from your local branches. Worktrees share the object store, so they're near-instant to create and trivially cheap. Shared directories are not an option; don't let "it's just two quick tasks" tempt you.

**Four is my ceiling, and the bottleneck is me.** Agents don't get slower with more parallelism — *supervision* does. Each additional agent adds another stream of questions, another integration branch, another definition-of-done to verify. At five or six I stop actually reviewing and start rubber-stamping, which defeats the point. Your ceiling might differ; you'll know you've passed it when you stop reading diffs.

**Not every backlog is parallel.** I now sort tasks into "embarrassingly parallel" (mechanical migrations, test backfills, doc passes — disjoint by nature) and "inherently serial" (anything touching core abstractions that everything else imports). Forcing serial work into parallel sessions is how you end up re-doing three branches after the fourth changes the interface they all depend on.

**Make agents commit early and often on their own branch.** My task contracts require a commit at every meaningful checkpoint. When an agent goes sideways (one decided mid-task to "improve" an unrelated module ⚠️), `git log` on its branch tells me exactly where the plot was lost, and I reset to the last good commit instead of restarting the whole task.

Two things I'm actively experimenting with:

`watch cat status.log` replaces tab-hopping. Interrupt-driven supervision is good; glanceable supervision would be better.
Running agents in parallel isn't a Claude Code feature you turn on — it's a workflow you design. Isolate with worktrees, decompose with explicit ownership, integrate serially. Get those three right and the multiplier is real.

If you've built your own multi-agent setup — especially if you've pushed past four agents without losing the plot — I'd genuinely love to hear how you handle integration. Drop a comment 👇, and **follow me here on Dev.to** for more write-ups on running AI coding agents against real codebases. ✅
