I read the docs on git worktrees for parallel coding agents, saw "3 to 5 agents is the sweet spot," and did the only responsible thing: I ran six. If five is good, six is one better — the same logic by which a sixth coffee finally makes me productive instead of vibrating at the frequency of a struck tuning fork. Reader, it did not make me productive. It made a crime scene.
This is a field report. There's a real workflow buried in here. You'll have to step over some bodies to find it.
What a worktree actually is (the one thing that worked)
A git worktree is a second working directory checked out from the same .git repo. Own branch, own files on disk, shared history and objects underneath.
git worktree add ../boostor-agent-1 -b agent/1
git worktree add ../boostor-agent-2 -b agent/2
# ...and so on, six times, like an idiot
Now Agent 1 lives in ../boostor-agent-1 on branch agent/1, scribbling on its own copy of the files. Agent 2 is in its own directory. They literally cannot overwrite each other's edits, because they aren't editing the same files. If you've ever had two agents in one directory turn App.tsx into modern art because both wrote to it half a second apart, worktrees fix exactly that.
That's it. That's the part that works. Worktrees solve file collisions. Which would be a clean win, if files were the only thing six agents fight over. They are not.
The carnage, in chronological order
Round 1: Port 3030. Agent 1 boots its dev server, grabs port 3030. Agent 2 boots, also wants 3030, eats EADDRINUSE, and — being an "agent" — does not conclude "ah, taken, I'll use 3031." It concludes "interesting, let me investigate the networking stack." Forty thousand tokens later it has theories. This is Trigger.dev's documented worktree gotcha, and I lived it: worktrees give each agent its own files, not its own ports.
Round 2: the shared Postgres. All six worktrees point at the same database, because the connection string lives in .env and I am one person with one local Postgres. Two agents ran migrations within seconds of each other. The schema is now a superposition of both — half Agent 3's columns, half Agent 5's, fully nobody's. Isolated files, shared runtime. That's the fight to the death. They never fought over the code. They fought over port 3030 and a database, like roommates splitting one fridge.
Round 3: the body count on disk. Each worktree is a full checkout, so each one wants its own node_modules. Six agents, six pnpm install, six copies of every dependency you've ever regretted installing. A Cursor user reported automatic worktree creation burning 9.82 GB across two worktrees in a 20-minute session, and 20+ worktrees hitting ~140 GB over a week before they noticed. I believe them. My fan achieved liftoff. My SSD filed a grievance.
Round 4: the agent that "fixed" main. Here's the one that actually scared me. Claude Code worktrees branch from origin/HEAD by default — clean, off the default branch. But flip worktree.baseRef: "head" and new worktrees inherit your current state. Pair a misconfigured base with an agent enthusiastic enough to commit-and-push, and it will "helpfully" land work on, or right next to, main. Mine rewrote a config file, declared the build "fixed," and committed it with the confidence of a man who has never been wrong and also never been right. Our AGENTS.md says main is the single source of truth. The agent read that as a dare.
The referee, or: imposing order on the dogpile
The problem isn't the worktrees. Worktrees are doing their one job perfectly. The problem is that nobody is coordinating the work — six agents grabbing whatever, racing for the same ports and the same rows.
So you need a referee: a layer that hands out non-overlapping tasks and reaps the losers. The good news is you don't have to invent it from scratch — Claude Code ships the pattern as agent teams. A Team Lead decomposes the work into a shared task list with dependency tracking and file locking; teammates self-claim tasks and message each other. That's a referee. My homemade version was a JSON file and a shell script that did roughly the same thing with 100% more profanity:
# poor-man's referee: claim a task or get out
claim() { flock /tmp/tasks.lock -c "jq -r '.[] | select(.owner==null) ...'"; }
The other half of refereeing is kill criteria. Addy Osmani's rule: if an agent is 3+ iterations stuck on the same error, stop it. It is not going to crack it on attempt four; it's going to discover new and exciting ways to spend your money. My referee got a mercy rule. Three strikes and you're kill %1.
And the env-file pain from Round 2 has a one-liner fix I wish I'd known first. Worktrees are fresh checkouts, so gitignored .env files don't come along for the ride, and agents silently boot with no config. Claude Code reads a .worktreeinclude (gitignore syntax) and copies matched-but-ignored files into each new worktree:
.env
.env.local
What actually survived
Strip away the bodies and a workflow is standing there, slightly singed:
- One worktree per agent, one isolated branch.
git worktree add ../agent-x -b agent/x, orclaude --worktree feature-x. Never two agents per directory. - A
.worktreeinclude, so each checkout actually has its secrets instead of failing on an empty config. - A referee — agent teams' shared task list plus file locking, or your own lockfile script — so agents claim non-overlapping work instead of racing for it.
- Per-worktree ports, DBs, and services. This is the step everyone skips and it is the entire game. Give each agent its own port and its own database (or at least its own schema). Do not make six agents share one Postgres unless you enjoy migrations with trust issues.
- Cap at 3–5. Every authoritative source converges here; Osmani notes 3–5 "consistently outperforms larger teams," and token cost scales linearly with team size. I paid for six and the sixth agent's entire contribution was breaking
main. I did the math so you don't have to: I bought more conflicts. - Kill criteria, enforced — 3 strikes, reap. Not vibes.
- Clean up.
git worktree remove ../agent-x. Claude Code auto-removes the clean ones and prompts on dirty ones, which is more grace than my agents extended to my database.
The twist: maybe the answer wasn't worktrees at all
Here's the part that stings. After all this — the six installs, the 140-GB-curious disk usage, the migration séance — Trigger.dev publicly ditched worktrees for GitButler virtual branches: multiple branches applied to a single working directory. No duplicated node_modules, no six dev servers, no port 3030 thunderdome. The agent just routes its changes to the right branch:
but commit --changes "agent-3's work"
One directory, many branches, one node_modules. All the parallelism, none of the disk-space body count.
And the tooling churns under you while you read this: JetBrains shipped first-class worktree support in 2026.1, Cursor 2.0 built Parallel Agents straight on worktrees, Crystal got renamed to Nimbalyst, Conductor runs each agent in its own worktree on macOS, and Vibe Kanban's parent Bloop announced shutdown in early 2026 (the project lives on as community open source). Pick a hill; it's already being regraded under your feet.
So did the six-agent worktree colosseum work? No. One of them fixed main into a smoking hole and I had to git reflog my way back to dignity. But the survivors — isolated branches, a referee, per-agent services, a hard cap of five, and a mercy rule — are a genuinely good way to run git worktrees for parallel coding agents. Just run five. Or honestly: try virtual branches and skip the disk-space funeral entirely.
I'd write a proper conclusion, but two agents are arguing over port 3030 again and I have to go pull the plug on %1.
