AI + Git Worktree: a multi-agent setup that actually works
Tuesday, March 24, 2026 · 6 min read
AI coding agents are reshaping how we build software and git worktree turned out to be the missing piece for running them in parallel.
The method. Structure first.
I work at Lago, an open source platform for metering and usage-based billing. React frontend, Rails API, event-driven architecture...not a codebase you want to throw a half-baked prompt at, so over time I've organized my work around 3 steps that keep things on track and that work, at least for me:
Step 1: Technical Solution. Before touching any code I write up what needs to be built. Not a novel, just enough to make the architecture and the key decisions clear. This is the part that actually requires thinking. Get it wrong here and everything downstream suffers.
Step 2: Vertical ticket breakdown. The technical solution gets split into tickets. And here's the thing: these aren't tickets to make a PM feel good. They're dense technical documents with architectural reasoning, edge cases and enough context that an agent can pick one up and actually run with it. The size depends on complexity: sometimes it's 1 ticket, sometimes it's 8.
Step 3: Claude Code as executor. Each ticket goes to Claude Code along with the technical solution as background context. One agent, one ticket, one well-defined scope. The narrower the scope, the better the agent performs.
Pretty straightforward so far. Lots of people are doing some version of this.
The bottleneck. one ticket at a time.
Here's where it starts to break down.
Once I have all the tickets lined up I can see the entire feature in front of me and since each ticket is self-contained there's no reason they need to run sequentially. The problem is that git only lets you work on one branch at a time in a single directory, so in practice you're stuck doing one ticket after the other.
The workarounds are not very effective to me:
- Clone the repo multiple times: works until it doesn't, wastes disk space and quickly turns into a mess
- git stash + manual checkout: fragile, error-prone and you're still switching context instead of running things in parallel
- Third-party tools: extra dependencies that add complexity without solving the core issue
And it gets worse in a real product setup. If your feature touches multiple repos, or depends on a branch that's still being worked on in another service, coordinating all of that by hand is genuinely awful.
The solution. git worktree.
This is where git worktree comes in. Shipped in July 2015 and honestly I'd never really explored it. Never had the right reason to and that's on me. But the multi-agent use case makes it actually essential.
The idea is simple: instead of cloning a repo multiple times you can have multiple working directories all pointing at the same .git object. Each directory lives on its own branch. No duplication, all worktrees share the same remote and the whole thing is one command.
Basic flow
cd ~/projects/my-app
# Create a worktree for the parallel ticket starting from the epic branch
git worktree add -b feature/dashboard-filters ../my-app-filters feature/dashboard
cd ../my-app-filters
# Work on the ticket
git add .
git commit -m "feat: add date range filter to dashboard"
git push -u origin feature/dashboard-filters
# Go back to main work
cd ../my-app
# Once the ticket is merged
git worktree remove ../my-app-filtersYou can branch off feature/dashboard, main or anything else. When tickets share the same base the final merge tends to be clean. Conflicts can still happen if two tickets touch the same files but at least you see them coming.
Why this matters for multi-agent setups
Each agent gets its own worktree. No stepping on each other, no shared state, no one agent undoing what another just did. Beyond that:
- Real parallelism: multiple terminals, multiple agents, each focused on one thing
- Independent testing: spin up each feature in isolation before merging anything
- Cleaner PRs: each one scoped tightly which makes reviews actually readable
Beyond the basics. Orchestrating a real architecture.
The simple case above works great for flat projects or monorepos with no external dependencies.
Real architectures aren't gentle.
At Lago we have a React frontend, a Rails API, a database, Redis and more all in play. Each worktree isn't just a branch. It's an environment. It needs its own ports, it needs to know which services to talk to and it needs to coexist with every other environment running at the same time without conflicts.
lago-worktree. A bash script to orchestrate it all.
My main work is on the frontend so I built a bash script to handle the orchestration starting from that layer. The idea is simple: each ticket gets its own worktree, its own port, its own isolated environment. If a ticket only touches the UI, the script creates a fresh frontend worktree on a free port and points it to the API already running from the main stack. If the ticket touches both frontend and API, it spins up dedicated worktrees for each. One command either way. Once every worktree is up, I can assign an agent to each one and let them all work in parallel, each focused on its own ticket without stepping on the others.
Frontend-only ticket:
lago-worktree create feat-01
# Front available at http://localhost:3001
# API shared with the main stack on :3000Ticket touching both frontend and API:
lago-worktree create feat-02 --from-front=feat/ui --from-api=feat/endpoint
# Front available at http://localhost:3002
# Dedicated API at http://localhost:4001See what's running:
lago-worktree ps
# NAME FRONT API STATUS
# feat-01 http://localhost:3001 [main] shared running
# feat-02 http://localhost:3002 [feat/ui] http://localhost:4001 [feat/...] runningClean up when done:
lago-worktree destroy feat-02
# Removes the branch and directory of the front worktree
# Removes the branch and directory of the API worktreeThe frontend and API get their own isolated instance per ticket. Database, Redis and the event streaming layer stay shared across all worktrees since every agent works against the same data and there's no need to duplicate them. This keeps resource usage low and setup fast. If the need arises to isolate other layers per worktree, the script is designed to be extended: just add a new flag for that layer and the orchestration handles the rest.
Parallelism works. I don't.
So now I have multiple independent instances of the full architecture running in parallel, each with a dedicated agent grinding through its ticket.
What's next? Well, the bottleneck now is me.
Agents produce code at a pace I can't keep up with when it comes to reviewing it and making sure it actually matches the solution. The more efficient the system gets the more obvious this gap becomes.
There's also a bigger shift worth naming: I almost stopped writing code and started directing it, context, architecture, vision, while the agents handle the execution. That could be a good thing, maybe, but it comes with a catch: the quality of what comes out is directly tied to the quality of my thinking. A vague ticket produces vague code, a wrong assumption gets implemented perfectly. Garbage in, garbage out and with agents it happens faster than ever.
How do I solve it? I don't know yet. But that's the kind of problem worth having.