From One Agent to Many: The Worktree Way
Or: How to Run Multiple Workstreams Without Losing Your Mind
The Problem with Naive Parallelism
Section titled “The Problem with Naive Parallelism”“Just open multiple IDE windows and run multiple agents!”
Sure. Try it. I’ll wait.
You’ll immediately hit conflicts:
Naive parallelism doesn’t work. You need isolation. Real isolation. The kind where your agents can’t even see each other, let alone interfere.
Git Worktrees: The Foundation
Section titled “Git Worktrees: The Foundation”Git worktrees solve the fundamental problem: multiple working directories, one repository.
# Main worktree~/projects/myapp/├── .git/├── apps/└── node_modules/
# Additional worktrees (isolated)~/projects/myapp-issue-42/├── apps/└── node_modules/ # Copy-on-write from main
~/projects/myapp-issue-43/├── apps/└── node_modules/ # Copy-on-write from mainEach worktree:
- Has its own branch (no conflicts)
- Has its own working directory (no file conflicts)
- Shares git history (no duplication)
- Can have its own ports and database
It’s like having multiple parallel universes, except they all share the same timeline and you can merge them back together when you’re done.
Worktrunk Configuration
Section titled “Worktrunk Configuration”Managing worktrees manually is tedious. Like, “I’d rather just do the work myself” tedious. Worktrunk (wt) automates setup with hooks. For more details see the worktrunk github repo.
[post-create]# Copy environment from mainenv = "cp {{ main_worktree_path }}/.env . 2>/dev/null || cp {{ main_worktree_path }}/.env.example .env"
# Configure unique ports and databaseconfig = """API_PORT={{ branch | hash_port }}WEB_PORT={{ ('web-' ~ branch) | hash_port }}DB_NAME="myapp_{{ branch | sanitize }}"
sed -i.bak "s|^PORT=.*|PORT=${API_PORT}|" .envsed -i.bak "s|^VITE_PORT=.*|VITE_PORT=${WEB_PORT}|" .envsed -i.bak "s|\\(DATABASE_URL=.*:[0-9]*/\\)[^?]*|\\1${DB_NAME}|" .env"""
# Copy node_modules (instant on APFS)deps = """if cp -c /dev/null /dev/null 2>/dev/null; then cp -c -r {{ main_worktree_path }}/node_modules . 2>/dev/null || npm installelse npm installfi"""
# Create isolated databasedb = "npm run wt:db:create && npm run db:migrate"
[pre-remove]# Clean up database when removing worktreedb-cleanup = "npm run wt:db:drop 2>/dev/null || true"What this does:
- Copies
.envwith unique ports (deterministic hash) - Creates isolated database per worktree
- Copies
node_modulesinstantly (copy-on-write magic) - Cleans up database when worktree is removed
Issue-Driven Workflow
Section titled “Issue-Driven Workflow”Shell functions for issue-driven development:
# Create worktree and launch agent for an issuewti() { local issue_num="$1" local branch_name="issue-$issue_num"
wt switch -c "$branch_name"
if [ $? -eq 0 ]; then opencode --prompt "read AGENTS.md and start work on issue $issue_num" fi}
# Remove worktree when donewtr() { local issue_num="$1" wt remove "issue-$issue_num" -D}Usage:
wti 42 # Create worktree, launch agent for issue #42wtr 42 # Clean up when doneTwo commands. That’s it. Create a fully isolated workspace with its own branch, ports, and database, launch an AI agent with context, and point it at a specific issue.
Parallel Execution in Practice
Section titled “Parallel Execution in Practice”Morning Workflow
Section titled “Morning Workflow”# Spin up agentswti 42 # Agent works on authenticationwti 43 # Agent works on data exportwti 44 # Agent works on UI improvements
# Monitor progresswt list# + main ~/projects/myapp# issue-42 ~/projects/myapp-issue-42 http://localhost:12847# issue-43 ~/projects/myapp-issue-43 http://localhost:14521# issue-44 ~/projects/myapp-issue-44 http://localhost:16893
# Review PRs as they complete# Agent: "Feature #42 ready for review. PR url: ..."
# Ask for changes, improvements# Agent addresses the points# Final review
# Tell Agent to finalize
# Cleanupwtr 42wtr 43wtr 44Result: Three features in no-time, with supervision where it counts.
You’re not writing most of the code. You’re reviewing end results. You’re making architectural decisions. You’re doing the parts of the job that actually require a human brain. Orchestrating.
Why This Beats “Fire and Forget”
Section titled “Why This Beats “Fire and Forget””Tools like the Ralph Wiggum loop run agents indefinitely until completion. The parallel worktree approach is different:
| Fire and Forget | Issue-Driven Worktrees |
|---|---|
| Single long-running agent | Multiple scoped agents |
| No isolation | Full isolation (branch, ports, DB) |
| Completion = agent decides | Completion = PR reviewed |
| Hard to monitor | Easy to check wt list |
| Hard to abort | Just wtr <issue> |
| No review until end | Sub-agent review per PR |
Each agent is scoped (one issue, one branch, one PR), isolated (can’t interfere with others), reviewable (work visible in PR before merge), and disposable (easy to abort and clean up).
Deterministic Ports
Section titled “Deterministic Ports”API_PORT={{ branch | hash_port }}This hashes the branch name to generate a port between 10000-19999.
Why this matters:
- Same branch always gets same ports. Predictable.
- No collisions between worktrees. Ever.
- Predictable URLs for bookmarking.
- No manual configuration.
Database Isolation
Section titled “Database Isolation”Each worktree gets its own PostgreSQL database:
# Main worktreeDATABASE_URL=postgresql://localhost:5432/myapp
# Issue 42 worktreeDATABASE_URL=postgresql://localhost:5432/myapp_issue-42This is the thing that makes parallel agents actually work. Without database isolation, you’re just running multiple agents that randomly break each other’s tests. With it: no test interference, clean state per worktree, automatic cleanup on removal.
Copy-on-Write Dependencies
Section titled “Copy-on-Write Dependencies”The fastest install is no install.
# macOS APFScp -c -r main/node_modules .
# Linux btrfs/xfscp --reflink=auto -r main/node_modules .Copy-on-write means instant “copy” (just metadata), no disk space until files modified, and 500MB of node_modules in less than 1 second. Without it, each worktree needs 30-60 seconds for npm install.
Scaling Limits
Section titled “Scaling Limits”Practical limits per machine:
- ~500MB disk per worktree (node_modules)
- ~200MB RAM per dev server
- ~100MB RAM per database
- 2 ports per worktree
Human attention limits:
- 1-2 agents: Easy, minimal supervision
- 3-4 agents: Optimal balance
- 5-6 agents: Requires more monitoring
- 7+: Diminishing returns
Troubleshooting
Section titled “Troubleshooting”Port Already in Use
Section titled “Port Already in Use”lsof -i :12847kill -9 <PID>Something’s squatting on your port. Evict it.
Database Connection Errors
Section titled “Database Connection Errors”npm run wt:db:createnpm run db:migrateDatabase doesn’t exist or isn’t migrated. Create it. Migrate it. Move on.
Worktree Already Exists
Section titled “Worktree Already Exists”wt listwt remove issue-42wt switch -c issue-42Clean up the old one, create a fresh one.
Agent Confused About Environment
Section titled “Agent Confused About Environment”AGENTS.md should include clear boundaries. Agents need to know: “You are working in a git worktree. The human orchestrator manages worktree creation/removal. Your job is feature implementation. DO implement features, write tests, create PRs. DO NOT create worktrees, remove worktrees, switch branches.”
Getting Started
Section titled “Getting Started”Step 1: Single Worktree
Section titled “Step 1: Single Worktree”brew install worktrunk/tap/wt# Create .config/wt.tomlwt switch -c test-feature# Verify ports, database workwt removeGet comfortable with the basics. Make sure everything works.
Step 2: Two Parallel Agents
Section titled “Step 2: Two Parallel Agents”wti 42 # Simple bug fixwti 43 # Documentation update# Monitor both, get comfortableStart small. Two agents on simple tasks. Get used to the rhythm.
Step 3: More Parallel Agents
Section titled “Step 3: More Parallel Agents”wti 44 # New featurewti 45 # Refactoringwti 46 # Tests# Practice monitoring and unblockingAdd a third. Or a fourth. Find your personal limit.
Step 4: Optimize
Section titled “Step 4: Optimize”- Add shell functions (wti, wtr)
- Refine AGENTS.md worktree section
- Find your optimal parallel count
Conclusion
Section titled “Conclusion”Parallel agent execution changes how you work:
Before: Implement features sequentially, wait for each to complete, context-switch constantly, lose half your productivity to “where was I again?”
After: Orchestrate multiple features simultaneously, review in batches, maintain focus, actually use your brain for the hard problems
The key enablers: git worktrees for isolation, Worktrunk for automation, deterministic ports, isolated databases, issue-driven workflow, and clear agent boundaries in AGENTS.md.
Result: 3-4x throughput with maintained quality.
The future isn’t one developer, one feature at a time. It’s one developer orchestrating multiple AI agents, each on isolated features, all in parallel.
See Effective AI-Augmented Development for the full framework, or Case Study: Self-Correcting Test Isolation for guardrails in action.