How to Run Coding Agents in Parallel with Git Worktrees

A step-by-step guide to running Claude Code and Codex sessions in parallel using git worktrees: creating them, making them runnable, reviewing the output, and merging without collisions.

Karl Wirth · · Updated August 14, 2026
How to Run Coding Agents in Parallel with Git Worktrees

Two coding agents in one working directory will overwrite each other. One is refactoring the API layer, the other is updating the frontend, both rewrite package.json, and the loser’s changes disappear without an error message. You find out when the tests fail an hour later.

Git worktrees fix this at the file system level. Each session gets its own directory on its own branch, sharing one .git database, so parallel agents never touch the same file on disk. This guide walks the full loop: creating the worktree, making it actually runnable, splitting work so the agents do not collide semantically, reviewing what came back, and cleaning up.

Quick answer

  • Create one worktree per session. git worktree add -b feat/auth ../myapp-auth, then start your agent inside that directory.
  • Claude Code can do it for you. claude --worktree feature-auth creates .claude/worktrees/feature-auth/ on a branch named worktree-feature-auth and starts the session there.
  • Codex uses the git command plus --cd. codex --cd ../myapp-api starts a Codex session in a worktree you created with git.
  • A fresh worktree is not a working project. Install dependencies, copy your gitignored env files, and give each worktree its own ports and scratch database before you fan out.
  • One branch checks out in one worktree. Git refuses to check the same branch out twice unless you pass --force, so mint a unique branch per session rather than forcing it.
  • Review is the bottleneck. Worktrees make it cheap to start five agents. They do nothing to make five diffs cheap to read.

What a worktree gives you

A git worktree is a second working directory linked to the same repository. It has its own files, its own index, and its own branch checkout. It shares the repository’s commit history and remotes, so merging is an ordinary merge and there is no second clone to keep in sync.

~/projects/myapp/          branch: main
~/projects/myapp-auth/     branch: feat/auth-refactor
~/projects/myapp-api/      branch: feat/api-endpoint

For agents specifically, three things change. Edits in one session cannot reach files in another. Each session’s uncommitted work stays out of the other sessions’ context, so an agent reading the repo does not see half-finished work it was never told about. And each session commits to its own branch, which means you can accept one agent’s work and throw away another’s without unpicking a shared commit.

Step 1: create the worktree

With git directly

The portable option, and the one to use when you want the worktree in a specific place or on a branch that already exists.

cd ~/projects/myapp

# New directory on a new branch
git worktree add -b feat/auth-refactor ../myapp-auth

# New directory on an existing branch
git worktree add ../myapp-api feat/api-endpoint

# See what exists
git worktree list

Git refuses to check the same branch out in two worktrees, and reports fatal: 'feat-one' is already used by worktree at ... when you try. --force overrides the refusal, which is worth knowing and worth avoiding: two agents committing to one branch is the collision worktrees exist to prevent. Give each session its own branch.

Start the agent in it:

cd ../myapp-auth
claude          # or: codex

With Claude Code’s built-in flag

Claude Code creates and enters a worktree in one command. Pass --worktree (or -w) with a name:

claude --worktree feature-auth

By default the worktree lands at .claude/worktrees/feature-auth/ inside the repository, on a new branch named worktree-feature-auth, branched from the repository’s default branch on the remote. Run the same command with a different name in another terminal to get a second isolated session. Omit the name and Claude Code generates one.

Two settings are worth knowing on day one. Add .claude/worktrees/ to .gitignore so worktree contents do not show up as untracked files in your main checkout. And if you want new worktrees to branch from your current work rather than from a clean main, set worktree.baseRef in settings:

{
  "worktree": {
    "baseRef": "head"
  }
}

You can also start a worktree from a pull request by passing the number, quoted so your shell does not read # as a comment:

claude --worktree "#1234"

With Codex

Codex has no worktree flag of its own, so create the worktree with git and point Codex at it. The --cd flag (short form -C) sets the working directory:

git worktree add -b feat/api-endpoint ../myapp-api
codex --cd ../myapp-api

The same flag works on codex exec for non-interactive runs, which is how you script a batch of parallel Codex jobs across several worktrees.

Step 2: make the worktree runnable

A worktree is a fresh checkout of tracked files, so everything git ignores is missing. This is the step people skip, and it is why the second agent spends twenty minutes discovering that the app will not boot.

Install dependencies. Each worktree needs its own node_modules, .venv, target, or equivalent. Run your project’s install command in the new directory before the agent starts work, or tell the agent to run it as its first action.

Carry your env files across. Claude Code reads a .worktreeinclude file at the project root, using .gitignore syntax, and copies matching files that are also gitignored into every worktree it creates:

.env
.env.local
config/secrets.json

For worktrees you create by hand with git worktree add, copy those files yourself.

Give each worktree its own runtime. Worktrees isolate files, not ports, databases, or external accounts. Five agents each running npm run dev on port 3000 fail loudly, which is the good case. Five agents sharing one development database or one sandbox payment account fail quietly and leave you unable to attribute anything. Assign a port range per worktree, point each at its own scratch database, and keep shared external credentials out of parallel runs.

Step 3: split the work so agents do not collide semantically

Worktrees stop two agents writing the same file. They do nothing about two agents changing the same behaviour from opposite ends of the codebase, which merges cleanly and breaks at runtime.

The reliable fix is task decomposition rather than tooling. Before you fan out, write down which files or modules each session owns, and put that boundary in the prompt: “work only inside src/auth/, and if you need a change outside it, stop and tell me instead of making it.” Agents follow an explicit ownership boundary well, and a session that stops to ask is much cheaper than a session that quietly edits a shared type.

Three patterns cover most parallel work:

Independent features. Each session takes a feature that touches a different part of the tree. The default, and the only pattern that scales past three sessions.

Stacked work. Session two depends on session one’s output. Do not run these at the same time. Branch the second worktree from the first branch once the first is committed, using git worktree add -b feat/step-2 ../myapp-step-2 feat/step-1.

Competing attempts. Two sessions attempt the same task with different instructions, one worktree each, and you keep the better result. Expensive in tokens and cheap in coordination, which makes it a good use of parallelism when you genuinely do not know which approach is right.

Step 4: keep track of what is running

Once three sessions are live in three directories, the hard part stops being isolation and starts being attention. Claude Code ships a view for this:

claude agents          # every session, grouped by state
claude agents --json   # the same list as structured output
claude attach <id>     # jump into one

Sessions needing your answer or a permission decision are grouped separately from sessions that are still working, which is the distinction that matters when you are deciding where to look next. For the wider version of this problem, including reading what an agent actually did before you accept it, see how to manage and review multiple agent sessions.

Step 5: review before you merge

Run the diff from inside the worktree, against the branch you will merge into:

cd ~/projects/myapp-auth

git diff main --stat                    # scope: which tracked files, how much
git status --short                      # staged, unstaged, and untracked changes
git diff main -- src/auth/              # the changes themselves, by area
git log main..HEAD --oneline --reverse  # commits unique to this branch, oldest first

Substitute your own merge target for main if the repository uses master, develop, or a release branch. Without a local ref of that name, git answers fatal: ambiguous argument.

Run git status --short alongside the diff rather than instead of it. git diff compares tracked content only, so a file the agent created and never staged does not show up in it, which is exactly the change you least want to miss.

Read the --stat output first. A session told to change one module that touched twenty files did something you have not been told about, and that is worth knowing before you read a single line of the diff.

Then merge from the main checkout and run the tests:

cd ~/projects/myapp
git merge feat/auth-refactor
npm test

Merge one branch at a time and run the tests between merges. Two agent branches that each pass on their own can fail together, and finding out which one caused it is much easier when only one landed since the last green run.

Step 6: clean up

Worktrees are cheap but not free, and stale ones accumulate fast when you are running several sessions a day.

git worktree remove ../myapp-auth
git worktree list                    # confirm it is gone
git worktree prune                   # drop records for directories deleted by hand

If git refuses because the worktree is locked, run git worktree unlock ../myapp-auth first, naming the worktree; the bare command prints a usage error. If it refuses because of uncommitted changes or untracked files, look at what is there before reaching for --force, because that is the branch of this workflow where work actually gets lost.

Claude Code handles its own cleanup on exit. An unnamed session with a clean worktree gets removed automatically. A session with changes or new commits prompts you to keep or remove it. Non-interactive runs started with -p have no exit prompt, so their worktrees stay until a later sweep or a manual git worktree remove.

How many agents at once

The ceiling is your review capacity, not your machine.

SessionsWhat it feels like
1 to 2No overhead. You can hold both in your head.
3 to 4The sweet spot. Needs a session list, but the diffs stay readable.
5 to 6Review becomes the whole job. Only worth it if the tasks are genuinely independent.
7+You are approving work you have not read.

The number worth tracking is how many diffs you can genuinely read in an hour, rather than how many agents you can start.

What worktrees do not solve

Semantic conflicts. Covered above, and worth repeating because it is the failure that survives a correct worktree setup.

Shared runtime state. Ports, databases, caches, and any external account your tests touch.

Lockfile churn. Two agents adding dependencies produce two lockfiles that conflict at merge time and are miserable to resolve by hand. Keep dependency changes to one session at a time.

Knowing what each agent did. A worktree tells you which files changed. It does not tell you which commands the agent ran, what it tried and reverted, or why it made a decision. Answering those questions is a review problem, and it is where most of the remaining cost of parallel agents sits.

Tools that handle worktrees for you

Claude Code has the flag documented above, plus isolation: worktree in a custom subagent’s frontmatter when you want a delegated task to run in its own checkout.

Nimbalyst makes a worktree a one-click option when you start a session. Choose Claude Code or Codex, choose whether the session runs in its own worktree on its own branch, and the session appears on a kanban board with its own transcript, its own files-changed sidebar, and file-by-file diff review before you commit. Merging is a review-and-accept step in the app rather than a terminal round trip. Nimbalyst is free for individuals and MIT licensed for individual-use features.

Plain shell works fine if you would rather not adopt anything. A function like this covers most of it:

agent-worktree() {
  local name=$1
  local repo=$(basename "$PWD")
  git worktree add "../$repo-$name" -b "agent/$name" || return 1
  cd "../$repo-$name" || return 1
  echo "Worktree ready at $PWD on branch agent/$name"
}

For a wider comparison of the tools built around this, see the best git worktree tools for AI coding.