The 3-Layer Isolation Stack: How to Run Multiple AI Agents in Parallel Without Losing Work
Git worktree isolation, copy-on-write snapshots, and port namespacing — the complete technical guide to safe parallel agent execution
If you have ever run two AI coding agents simultaneously and watched them silently overwrite each other's changes, you already understand the miscoordination problem. A 2024 developer survey found that 41% of developers have lost work due to agent conflicts — uncommitted edits stomped by a second agent, database migrations applied twice, or two processes binding to port 3000 at the same moment. The fix is not to run agents sequentially and sacrifice throughput. The fix is isolation.
This guide walks through the 3-layer isolation stack that makes Git worktree isolation for AI agents practical: filesystem separation via Git worktrees, stateful isolation via copy-on-write database snapshots, and network isolation via local port namespacing. Each layer addresses a distinct failure mode. Together they let you run Claude Code, Codex, Gemini, and other agents in true parallel — on the same repository, at the same time — without conflicts. We will also look at how Medley.sh wires all three layers together so you are not managing the stack by hand.
Why Parallel Agents Overwrite Each Other
The miscoordination problem has three distinct root causes, each corresponding to a layer of the stack.
Filesystem collisions happen when two agents share a working tree. Agent A edits src/auth/session.ts to add refresh-token logic. Agent B, working on a related ticket, reads the same file, makes its own changes, and writes them back. Depending on timing, one agent's work simply disappears. Git does not protect you here — both agents are writing to the same working directory, so there is nothing to merge.
Database state collisions are subtler. Agent A runs a migration that adds a user_preferences column. Agent B, starting from what it believes is a clean schema, runs a migration that also adds user_preferences. The second migration fails — or worse, silently succeeds with unexpected behavior — and now your schema is in an indeterminate state that neither agent's code expects.
Port conflicts are the most immediately visible. Two dev servers, two test runners, two mock API processes — they all want port 3000 (or 5432, or 6379). The second process crashes, the agent retries, logs fill with noise, and the human has to intervene.
Solving any one of these in isolation is not enough. A team that uses Git worktrees but shares a database will still hit migration conflicts. A team that isolates the database but shares a port namespace will still see process crashes. The stack must address all three layers.
Layer 1: Git Worktree Isolation for AI Agents
Git worktrees are the foundation of the isolation stack. Introduced in Git 2.5, a worktree lets you check out multiple branches of the same repository into separate directories simultaneously — without cloning the repo multiple times.
Setting Up a Worktree Per Agent
# Create a worktree for Agent A working on feature/auth-refresh
git worktree add ../project-agent-a feature/auth-refresh
# Create a worktree for Agent B working on feature/user-prefs
git worktree add ../project-agent-b feature/user-prefs
# List active worktrees
git worktree list
Each worktree is a fully independent working directory with its own index and HEAD. Agent A writes to ../project-agent-a/src/auth/session.ts; Agent B writes to ../project-agent-b/src/user/prefs.ts. They share the same .git object store (so you are not duplicating history), but their working trees are completely separate. There is no mechanism by which one agent can overwrite the other's uncommitted changes.
Why This Beats Branching Alone
You might wonder: why not just have each agent work on its own branch in the same working directory, switching branches between tasks? The answer is that AI agents are not polite about branch state. They run file-system operations, install dependencies, and sometimes write outside the tracked tree (think node_modules, build artifacts, .env.local). Switching branches mid-session leaves debris. Worktrees give each agent a clean, persistent sandbox that survives across sessions without any branch-switching ceremony.
Merging Back
When an agent finishes its mission, merging is standard Git:
cd ../project-agent-a
git add -A && git commit -m "feat: add refresh token rotation"
git push origin feature/auth-refresh
# Open PR as normal
# Clean up the worktree when done
git worktree remove ../project-agent-a
Conflicts, if any, surface at merge time — the right time — not as silent overwrites during execution.
Layer 2: Copy-on-Write Database Snapshots
Filesystem isolation solves the code layer. But if all your agents point at the same development database, you still have a shared mutable state problem.
The modern solution is copy-on-write (CoW) branching at the database layer. Neon is the canonical example: it is a serverless Postgres service that can create a full database branch — a logical copy of your schema and data — in under a second, with no storage duplication until writes diverge.
One Branch Per Agent Mission
# Using the Neon CLI
neonctl branches create --name agent-a-auth-refresh --parent main
neonctl branches create --name agent-b-user-prefs --parent main
# Each branch returns its own connection string
# Agent A uses: postgres://[email protected]/neondb
# Agent B uses: postgres://[email protected]/neondb
Agent A runs its migrations against its branch. Agent B runs its migrations against its own branch. Neither can corrupt the other's schema. When a mission completes successfully, you review the migration diff and apply it to main — the same review gate you would use for code.
Why Not Just Use SQLite or an In-Memory DB?
For many integration tests, SQLite is fine. But AI agents working on real features often need production-representative data — realistic row counts, foreign key relationships, existing seed data. A CoW branch of your actual development database gives you that fidelity at near-zero cost. Neon's branching is fast enough (sub-second) that Medley.sh can provision a branch automatically when it starts a new agent mission, and tear it down when the mission closes.
Layer 3: Local Port Namespacing
The third layer prevents network-level collisions. When multiple agents each spin up a dev server, a test database proxy, or a mock service, they need non-overlapping ports.
A Simple Port Allocation Convention
The most pragmatic approach is a deterministic port-offset scheme tied to the worktree or mission ID:
# Assign a base port per agent slot
AGENT_SLOT=1 # 0, 1, 2, 3...
BASE_PORT=3000
PORT=$((BASE_PORT + AGENT_SLOT * 10))
# Agent slot 0: ports 3000-3009
# Agent slot 1: ports 3010-3019
# Agent slot 2: ports 3020-3029
You encode this in a per-worktree .env.local file that the agent reads at startup:
# .env.local for agent-a worktree
PORT=3010
DB_PORT=5442
REDIS_PORT=6389
Using macOS Network Namespacing
For stricter isolation — particularly useful when agents run subprocesses you do not fully control — macOS's launchd and pfctl can enforce that processes in a given session only bind to their allocated range. This is advanced territory, but the principle is the same: each agent mission gets a declared port budget, and anything outside that budget is blocked at the OS level.
The practical takeaway: even without OS-level enforcement, a consistent .env.local convention eliminates the vast majority of port conflicts. The key is that the convention must be applied automatically — if a human has to remember to set it, it will eventually be forgotten.
Managing Parallel Workflows Safely with Medley.sh
The 3-layer stack is sound engineering. The problem is operational overhead: creating worktrees, provisioning database branches, assigning port slots, tracking which agent is working on which mission, and knowing when to merge. Done manually, this is enough friction that most teams skip it and accept the collision risk.
This is exactly the problem Medley.sh is built to solve.
The Attention Queue
Medley.sh is a macOS-native orchestration layer that routes coding missions across multiple AI agents — Claude Code, Codex, Gemini, Cursor, Kimi — from a single Attention Queue. Instead of managing a sprawl of terminal tabs and disconnected agent sessions, you submit missions to the queue and Medley.sh handles dispatch.
When a mission is dispatched to an agent, Medley.sh can automatically:
- Provision a Git worktree for the target branch
- Set the per-worktree
.env.localwith an allocated port range - Wire the agent's working directory to the isolated worktree
The result is that the isolation stack is applied consistently, every time, without manual steps.
Transparent Cost-Per-Task Accounting
Running multiple agents in parallel means running up multiple API bills simultaneously. Medley.sh tracks cost per mission, so you can see exactly what each task cost across whichever agents handled it. This makes parallel execution financially legible — you are not just watching a global token counter tick up, you are seeing cost attributed to specific work.
Local-First, Your Code Stays on Your Machine
Medley.sh runs on your Mac. Your source code never leaves your machine — it is routed to agents via their local CLI interfaces (Claude Code's CLI, Codex CLI, and so on), not uploaded to a third-party orchestration server. The isolation stack described in this guide is enforced locally, which means your proprietary code stays under your control even as you scale to multiple parallel agents.
From Chaos to Orchestrated Workflow
The before-and-after is stark. Before: four terminal tabs, each running a different agent, each pointed at the same working directory and the same database, with you manually watching for conflicts. After: one Attention Queue, four isolated missions running in parallel, each with its own worktree and port allocation, with Medley.sh surfacing the ones that need your attention.
Conclusion
Parallel AI agent execution is not inherently dangerous — it is dangerous without isolation. The 3-layer stack gives you the primitives you need:
- Git worktrees eliminate filesystem collisions by giving each agent its own working directory on its own branch.
- Copy-on-write database branches (Neon and similar) eliminate schema and data collisions by giving each agent its own database state.
- Port namespacing eliminates network collisions by giving each agent a declared, non-overlapping port budget.
Each layer is independently valuable. Together, they make true parallel execution safe enough to run in your daily development workflow — not just in CI.
If you want the stack applied automatically, without the manual overhead of provisioning worktrees and tracking port assignments, try Medley.sh. It is the orchestration layer that turns a collection of powerful but disconnected AI agents into a single, coordinated workflow — running on your Mac, with your code staying exactly where it belongs.