Running Parallel AI Agents on Isolated Git Worktrees for Small, Reviewable PRs
Running Parallel AI Agents on Isolated Git Worktrees for Small, Reviewable PRs
The biggest issue with agent-generated pull requests is they try to do everything at once. The agent sees a bug, fixes it, then notices a refactoring opportunity, takes it, then adds a feature while it is in there. The resulting PR touches 40 files across 3 unrelated concerns, and the reviewer just gives up.
The Problem With Big PRs
Code review quality drops off a cliff as PR size increases. A 50-line PR gets careful, line-by-line review. A 500-line PR gets a skim and an approval. A 2000-line PR gets "LGTM" from someone who opened it, scrolled for 10 seconds, and closed it.
This is not opinion - there is data on it. Research on code review behavior shows reviewers spend about 60 minutes on small PRs (under 200 lines) and actually improve quality. For large PRs (over 500 lines), review time does not scale proportionally and defect detection drops sharply after the first hour. The marginal review quality per additional line becomes close to zero.
When an AI agent produces monster PRs, the value of having an agent is undermined. You automated the coding but broke the review process.
The Worktree Approach
Instead of branch stacking - where you chain dependent branches on top of each other - run multiple agents in parallel on isolated git worktrees, each scoped to one concern.
A git worktree is a separate checkout of the same repository at a different path on disk. Multiple worktrees can exist simultaneously, each on different branches, without interfering with each other. The setup looks like this:
# Create worktrees for three parallel agents from main
git worktree add ../agent-api -b fix/api-validation
git worktree add ../agent-ui -b feat/checkout-component
git worktree add ../agent-tests -b fix/test-suite
# Verify all three are created
git worktree list
# /path/to/repo abc1234 [main]
# /path/to/agent-api abc1234 [fix/api-validation]
# /path/to/agent-ui abc1234 [feat/checkout-component]
# /path/to/agent-tests abc1234 [fix/test-suite]
Each worktree is a separate directory on disk. Agent A works on the API endpoint in ../agent-api. Agent B works on the UI component in ../agent-ui. Agent C fixes the test suite in ../agent-tests. They do not interfere with each other because they are working in completely separate directory trees.
Why This Is Better Than Shared Branches
The common alternative - multiple agents working on the same branch sequentially or with manual conflict resolution - breaks in predictable ways:
- Agent A modifies
auth.ts. Before Agent A finishes, Agent B reads the originalauth.tsand makes changes based on the old version. Now you have two divergent changes to reconcile. - One agent's incomplete refactoring breaks another agent's tests before either is done.
- The
git statusin a shared checkout becomes impossible to read when multiple agents have been touching files.
Worktrees eliminate all of this. Each agent has exclusive access to its own checkout. There is no shared mutable state between agents during development. Conflicts, if any exist, surface cleanly at merge time with a clear diff from each branch.
Claude Code explicitly supports this pattern - the documentation describes isolation: worktree as a subagent configuration option that gives each subagent its own isolated worktree automatically cleaned up after use.
Why This Works
- Isolation: each agent only sees the files in its worktree, so it cannot accidentally make changes outside its assigned scope
- Parallelism: all agents run simultaneously instead of sequentially, compressing elapsed time
- Clean PRs: each worktree produces a single-concern branch that maps to a small, reviewable PR
- Clean conflict resolution: if two agents touch the same file, you see it at merge time with clear context from each branch rather than untangled interleaved changes
The Scoping Discipline
The worktree setup only works if the task scoping is precise. Vague agent prompts produce scope creep even with worktree isolation.
Weak scoping: "Fix the login flow"
Strong scoping: "Fix the email validation bug in src/auth/validators.ts line 47 where validation accepts emails without a TLD. Only modify validators.ts and its test file. Do not touch any other files."
The explicit "do not modify any other files" constraint is worth including in every agent prompt for this workflow. Agents will sometimes identify related issues and fix them proactively - which is useful when you want comprehensive changes, and destructive to the worktree isolation pattern when you do not.
The End State
When three agents finish their parallel worktrees, you have:
- Three branches:
fix/api-validation,feat/checkout-component,fix/test-suite - Three PRs ready for review, each under 200 lines
- No merge conflicts between the branches (because the scoping kept them from touching the same files)
- A reviewer who can give meaningful attention to each one
The alternative - waiting for one agent to do all three things sequentially, producing a 600-line PR - takes longer and produces a review that is rubber-stamping rather than reading.
This post was inspired by a discussion on r/ExperiencedDevs (31 comments).
Fazm is an open source macOS AI agent. Open source on GitHub.