Orchestrating Parallel Agent Sessions Without Corrupting Your Repo
Two agents in one working directory will overwrite each other's work and then try to fix the resulting failures. Neither is misbehaving.
Why anyone runs several at once
Orchestration tooling has become its own product category — in August 2026 Spotify shipped Xirp, a macOS application whose entire purpose is running Claude Code, Codex and Gemini CLI sessions in parallel. That such a tool exists tells you the practice is common enough to productise.
The motivation is straightforward. Agent sessions are slow relative to typing, and much of that time is waiting. If three independent pieces of work exist, running them concurrently converts serial waiting into parallel waiting.
The catch is that "independent" is doing a lot of work in that sentence.
The failure that defines the problem
Two agents working in the same checkout will interfere. Not occasionally — reliably, in ways that are tedious to debug.
Agent A: reads src/models/user.py
Agent B: reads src/models/user.py
Agent A: writes src/models/user.py (adds a field)
Agent B: writes src/models/user.py (from its stale read — A's work is gone)
Agent A: runs the test suite (now failing, for reasons it cannot see)
Agent A: "fixes" B's code to make its own tests pass
Neither agent is misbehaving. Each is operating on a filesystem it reasonably assumes only it is changing. The last line is the expensive one — a spiral of corrections to changes nobody made deliberately.
One agent per working directory. Every workable pattern below is a different way of arranging that; none of them share a checkout.
Shared state that is not the filesystem
Separate directories is necessary and not sufficient. Several things sit outside the working tree and are shared regardless:
- A local database. Two agents running migrations against one Postgres instance will corrupt each other's schema. Each needs its own, which usually means a container per session.
- Fixed ports. Both start a dev server on 3000; the second fails, or worse, attaches to the first.
- Global package state. A globally installed CLI upgraded by one session changes behaviour under the other.
- Shared caches. A corrupted build cache propagates to every session using it.
Ports are the one that produces the most confusing failures, because the symptom is a test suite passing against another agent's server. Assign a port range per session and pass it through the environment rather than relying on defaults.
Isolation, three ways
Git worktrees
The lightest option that actually works. Multiple working directories from one repository, each on its own branch, sharing the object store.
git worktree add ../work-auth -b feature/auth
git worktree add ../work-search -b feature/search
git worktree add ../work-perf -b fix/perf
# one agent per directory, no shared state
Fast to create, cheap on disk, and each agent gets a genuinely separate checkout. The limitation is that build artifacts and installed dependencies are per-directory, so a heavy toolchain multiplies setup cost.
Containers
Stronger isolation, and the same containment you want for security reasons anyway. Each agent gets its own filesystem, its own environment, its own resource limits.
Two benefits meeting in one mechanism is a good sign you are on the right track: this is the same arrangement the security pillar argues for independently.
Separate machines or CI runners
For long-running work, cloud-hosted sessions remove the local resource constraint entirely. The trade is latency and a slower feedback loop.
Splitting work so it stays independent
Isolation prevents filesystem conflicts. It does not prevent semantic ones — two agents editing different files can still produce changes that do not compose.
| Splits well | Splits badly |
|---|---|
| Independent bug fixes in different modules | A refactor touching shared interfaces |
| Writing tests for existing code | Anything renaming a widely-used symbol |
| Documentation for separate subsystems | Changes to the same data model |
| Per-package dependency upgrades | A migration plus the code that depends on it |
The heuristic: if two tasks would be uncomfortable as simultaneous pull requests from two engineers, they will be uncomfortable as parallel agent sessions. The coordination problem is the same one, without the benefit of two people who can talk to each other.
Merging the results
Isolation solves conflicts during the work and relocates them to the end. Three branches that each pass tests independently can still fail together.
branch A: adds User.email_verified + tests → green
branch B: adds User.email_verified_at + tests → green
merge A, then B: two fields for one concept, both shipped
Neither agent did anything wrong. Neither could see the other's work. This is the ordinary hazard of concurrent development, and agents hit it more often than people do because they do not chat, do not attend standup, and have no peripheral awareness of what else is in flight.
Two mitigations. Merge one branch at a time and rebase the rest, so each subsequent agent sees its predecessor's work rather than the original base. And, before starting parallel work, settle any shared design questions yourself — the names, the interfaces, the data model. Those are exactly the decisions that cannot be made independently and then reconciled.
The constraint nobody plans for
Parallelism moves the bottleneck to review. Three agents producing changes in twenty minutes is three pull requests arriving at one human.
Reviewing agent-authored code is not faster than reviewing human code and is frequently slower, because you cannot rely on the author having understood the surrounding system. If review capacity is one change at a time, running three agents does not triple throughput — it triples the queue.
This is worth knowing before investing in orchestration. The gain is real when review is not the constraint, and illusory when it is.
Cost scales with sessions, not with people
One practical consideration that surprises teams on metered pricing: three parallel sessions cost roughly three times one session, and each carries its own full context overhead — system prompt, tool definitions, context files, and its own reading of the same shared files.
Three agents each reading the same five core files pay for those files three times. That overlap is invisible until someone looks at a bill, and it argues for splitting work along boundaries that minimise shared reading — which is the same advice as splitting to minimise semantic conflict, arrived at from a different direction.
A workable setup
- One worktree per task, created and removed with the task.
- Two or three concurrent sessions. Beyond that, attention fragments and review saturates.
- Tasks chosen to touch disjoint parts of the codebase.
- Each session produces a branch and a PR — never a direct push.
- Review serially, in the order they land.
Modest, and it captures most of the available benefit. The elaborate setups — a dozen agents, automatic task decomposition, agents reviewing each other — tend to produce more coordination overhead than they remove, which is the usual outcome when parallelism is added faster than the bottleneck moves.
One agent per working directory, always; worktrees are the cheapest way to arrange it. Split work the way you would split it between two engineers who cannot talk to each other. And check where your bottleneck actually is — parallel agents multiply the review queue, not the throughput, when review is the constraint.