One agent is fast. Three agents on three features at once is where the time really goes away, as long as they don't step on each other. Run two sessions in the same folder and they edit the same files, fight over the same branch and break each other's builds. The fix is to give every session its own working copy. Below is how to do that with Claude Code's built-in worktrees, with plain git, and with Codex, plus the parts that usually go wrong: ports, .env files, and knowing which session is waiting on you.
Quick answer
- One session per worktree.
claude --worktree feature-auth(orclaude -w feature-auth) creates.claude/worktrees/feature-auth/on a new branch and starts Claude there.Plain git works too:
git worktree add ../app-feature-a -b feature-a, then runclaudeinside that folder.Codex:
codex --worktreestarts a session in a new managed worktree.Copy
.envautomatically with a.worktreeincludefile (same syntax as.gitignore). Claude Code and the Codex app both read it.Give each worktree its own dev-server port, or two sessions will fight over
localhost:3000.- Get notified when a session needs input with a
Notificationhook, so you don't have to check every tab.
Why worktrees and not just more terminal tabs
A git worktree is a second (or tenth) checkout of the same repository, in its own folder, on its own branch, sharing one .git. Each session edits its own files, so:
- Two agents never overwrite each other's changes.
- Each one can run tests and builds without breaking the other's.
- You review and merge each branch separately, like a normal pull request.
Opening three tabs in the same folder gives you none of that. Subagents are a different thing. They split work inside one session and report back to it. Worktrees are for separate tasks you want to keep apart.
Method 1: Claude Code's built-in worktrees
Claude Code has worktree support built in:
claude --worktree feature-auth # or: claude -w feature-auth
claude --worktree # no name: Claude picks one, like bright-running-fox
claude --worktree "#1234" # start from a pull request
What happens:
- The worktree goes in
.claude/worktrees/<name>/at the repo root, on a new branch calledworktree-<name>. - By default it branches from the remote default branch. Set
worktree.baseRefto"head"if you want it to start from your local HEAD instead. - Using an existing name reopens that worktree.
- The repo needs at least one commit, or you get
Failed to resolve base branch "HEAD".
Cleanup is mostly automatic. When you exit, a clean, unnamed worktree is removed along with its branch. If there's work in it, Claude asks whether to keep it. To come back later, run claude --worktree <name> --resume.
Add the folder to .gitignore so worktrees never show up as changes in your main checkout:
.claude/worktrees/
You can also ask mid-conversation. Say "work in a worktree" and Claude moves the session into one. For big mechanical changes, /batch splits the work across 5 to 30 subagents, each in its own worktree.
Method 2: plain git worktrees (any agent)
If you'd rather control the folders yourself, or you use several different agents, plain git does the same job:
git worktree add ../app-feature-a -b feature-a # new folder, new branch
cd ../app-feature-a && claude # start the agent there
git worktree list # see them all
git worktree remove ../app-feature-a # done: remove it
git worktree prune # clean up folders you deleted by hand
Two rules git enforces:
- A branch can be checked out in only one worktree at a time.
git worktree addrefuses a branch that's already checked out somewhere else. git worktree removeonly removes clean worktrees. Commit or discard first, or pass--forceif you're sure.
Method 3: Codex
Codex CLI has a flag for the same thing:
codex --worktree # new interactive session in a managed worktree
codex exec --worktree "implement the next step"
codex fork <SESSION_ID> --worktree # branch an existing session into a worktree
The Codex app creates worktrees under $CODEX_HOME/worktrees, keeps the 15 most recent by default, and lets you move a chat between your local checkout and a worktree. To pick a session up again, use codex resume, or codex resume --last for the most recent one. Add --all to see sessions from other folders.
The three things that break
1. Dependencies and .env files
A worktree is a fresh checkout. Gitignored files don't come along, so node_modules, build caches and your .env are missing.
.env: create a.worktreeincludefile at the project root, using.gitignoresyntax. Files that match and are gitignored get copied into each new worktree:
.env
.env.local
- Dependencies: install them in each worktree (
npm install,pnpm install…), or just ask the agent to do it first. Every worktree has its own copies, so disk use grows. Remove worktrees you're done with.
2. Ports
Three sessions each running npm run dev all want localhost:3000. The second one fails or moves to some random port, and now you don't know which browser tab belongs to which branch. Common fixes:
- Put a different
PORTin each worktree's.env(3001, 3002, 3003…). - Derive the port from the worktree's name or path in a small setup script, so it's the same every time.
- Remember the other listeners too: a database, a Storybook, a websocket server.
Writing the port into the session's name (3002 checkout) makes it obvious which tab is which.
3. Knowing who needs you
With several sessions, the bottleneck becomes you: one session waits on a permission prompt for ten minutes while you watch another one. People on Hacker News say their practical limit is two or three sessions for exactly this reason. Open GitHub issues ask for a way to see which session is blocked without checking every tab.
Claude Code can tell you. Add a Notification hook to ~/.claude/settings.json (macOS example):
{
"hooks": {
"Notification": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "osascript -e 'display notification \"Claude Code needs your attention\" with title \"Claude Code\"'"
}
]
}
]
}
}
permission_promptfires when Claude has been waiting for your approval for a few seconds.idle_promptfires about a minute after it finished.- If nothing shows up, run
osascript -e 'display notification "test"'once and allow Script Editor in System Settings → Notifications. - Prefer a sound? Set
"preferredNotifChannel": "terminal_bell"instead, or useafplay /System/Library/Sounds/Glass.aiffas the hook command. - Inside tmux, add
set -g allow-passthrough onto~/.tmux.confso notifications get through.
Claude Code also has agent view (research preview): claude agents lists every background session with its state (Working, Needs input, Idle, Completed…). Start one with claude --bg "prompt", or send the current one there with /bg.
Naming and resuming sessions
Ten sessions called "Claude Code" are impossible to tell apart. Name them:
claude -n auth-refactorwhen you start, or/rename auth-refactorlater.claude --resume auth-refactorpicks it up again, even from a different worktree of the same repo.- In the
--resumepicker,Ctrl+Wshows the sessions from every worktree andCtrl+Bfilters by branch.
Don't resume the same session in two terminals. Both write to one transcript and it gets mixed up. Use /branch or --fork-session to split a conversation instead.
Tools that manage many sessions
If juggling terminal tabs gets old, these apps and tools wrap the same idea (one agent per worktree) in an interface:
- >Orca: free, open-source desktop app (macOS, Windows, Linux). Runs Claude Code, Codex and other CLI agents side by side, one worktree each.
- >Conductor: Mac app where each task gets its own workspace with a branch, terminal and diff, then a pull request.
- >claude-squad: terminal UI on top of tmux and worktrees (
cs). - >workmux and >ccmux: tmux-based setups with a list of sessions.
Watch the quota
Parallel sessions spend your plan faster. That isn't a bug, it's the trade. Claude Code's docs put it plainly: running several sessions or subagents at once multiplies token usage. Background sessions count against your subscription just like interactive ones. On Pro or Max, the 5-hour window and the weekly limit both run out sooner. Check where you stand with /usage before starting a big parallel push.
Where Aki fits
Aki is a free macOS app built by someone running ten-plus Claude Code sessions at once, for the two things that get hard at that scale:
- Which session needs me? A slim bar on the edge of the screen shows one ring per Claude Code or Codex session, grouped by project, with its state, the context it has used and what's waiting.
- Sending the fix to the right one. Press ⇧⌘A, point at what's wrong (an element in Chrome, an area, a terminal error), write a note, and send. A page on
localhost:3002goes to the session in the worktree serving port 3002. Otherwise it goes to the session you picked. No screenshot to paste, no wrong tab. - How fast the week is going. The same bar shows how much of Claude's and Codex's weekly limit you've used, and today's tokens at API prices.
It's Mac-only (Apple Silicon, macOS 14+). Typing straight into a session's tab works with Orca, and other terminals read marks through Aki's MCP server or the aki CLI. Marks stay on your Mac. There's no account.
FAQ
Can I run multiple Claude Code sessions at the same time?
Yes. Run each one in its own git worktree (claude --worktree <name>) so they don't edit the same files. Each worktree has its own folder and branch.
What does claude --worktree do?
It creates a worktree in .claude/worktrees/<name>/ on a new branch called worktree-<name> and starts Claude in it. When you exit, a clean, unnamed worktree is removed automatically. If there's work in it, Claude asks whether to keep it.
Why is my .env missing in the worktree?
A worktree is a fresh checkout, and gitignored files don't come along. List them in a .worktreeinclude file at the project root and Claude Code (and the Codex app) will copy them into new worktrees.
How do I run several dev servers from different worktrees?
Give each worktree its own port, for example a different PORT in each .env. Otherwise they all try to use the same localhost port.
How do I know when a Claude Code session needs input?
Add a Notification hook in ~/.claude/settings.json that shows a desktop notification or plays a sound. Or open claude agents to see every background session's state.
Does Codex support worktrees?
Yes. codex --worktree starts a session in a new managed worktree, and the Codex app manages worktrees under $CODEX_HOME/worktrees.
Sources
- https://code.claude.com/docs/en/worktrees
- https://code.claude.com/docs/en/common-workflows
- https://code.claude.com/docs/en/sessions
- https://code.claude.com/docs/en/agent-view
- https://code.claude.com/docs/en/agents
- https://code.claude.com/docs/en/hooks-guide
- https://code.claude.com/docs/en/terminal-config
- https://code.claude.com/docs/en/costs
- https://git-scm.com/docs/git-worktree
- https://learn.chatgpt.com/docs/developer-commands?surface=cli
- https://learn.chatgpt.com/docs/environments/git-worktrees
- https://news.ycombinator.com/item?id=47573483
- https://github.com/anthropics/claude-code/issues/36885
- https://github.com/stablyai/orca
- https://www.conductor.build/docs
- https://github.com/smtg-ai/claude-squad
- https://useaki.vercel.app