All articlesOne worktree per agent thread: the change that took me from 8 to 45 PRs a week

One worktree per agent thread: the change that took me from 8 to 45 PRs a week

By Allan Clempe

ai-agentsworkflowengineering

Last week was one of my best on record: 45 pull requests merged, up from 8 the week before. The plan going in was to test Zed as my agent harness and see whether a better editor got better results out of the agents. It didn't, or not much. The win came from somewhere else: giving every agent thread its own workspace, and never letting two threads share a checkout.

That's the short version. The longer version is four habits I'd copy tomorrow if I were starting over, one trade-off I haven't solved, and the numbers, which Clocktopus captured while I got on with the work.

Run one worktree per thread

The thing that actually changed last week is that I stopped running agents in the same checkout. Every thread got a git worktree of its own: same repository, its own branch, its own working directory. Four or five threads going at once meant four or five worktrees, and none of them could trip over another's uncommitted files or half-finished migration.

Zed made this easy. A workspace per worktree, a shortcut to jump between them, and I could move from thread to thread as fast as I could think. When I drifted back to the terminal mid-week (more on that below) the workspaces stayed. The editor turned out to be a nice way to organise worktrees, and the worktrees were the point.

The rule I'd keep from the week: the unit of parallelism is the checkout, not the chat window. Two agents in one directory are one agent with a concurrency bug.

Make new worktrees free

For the first two days, creating a worktree was the slow bit. The repo kept its env files in the root, so every git worktree add gave me a checkout that couldn't run. Copy the config across, pull the dev branch, install, and only then start the feature. Ten minutes of ceremony before the agent could do anything, several times a day.

Git hooks fix this. post-checkout fires when a worktree is created, and it can run whatever you like. Mine copies the env files from the main checkout, pulls a fresh copy of the dev branch and installs dependencies. After that a new worktree costs one command.

The two guards at the top matter. git worktree add calls the hook with a null old-HEAD from inside a worktree git-dir, and nothing else does, so a plain git switch never triggers it.

#!/usr/bin/env sh
# .githooks/post-checkout: runs only when `git worktree add` creates a worktree
[ "$1" = "0000000000000000000000000000000000000000" ] || exit 0
case "$(git rev-parse --absolute-git-dir)" in */worktrees/*) ;; *) exit 0 ;; esac

main="$(git rev-parse --path-format=absolute --git-common-dir)/.."
cp "$main"/.env* . 2>/dev/null
git pull --ff-only origin dev
pnpm install --prefer-offline

Point git at it once with git config core.hooksPath .githooks and commit the file so the whole team gets it.

Don't write it yourself, either. Describe what a new worktree needs to your agent and let it write the hook. It'll pay for itself in a day.

Inspect 20%, trust the ticket

My loop for the week: trigger the agent, go and refine tickets while it works, come back. When I come back I read about a fifth of what it did. If that fifth is heading in the right direction, the rest almost always is, and I move on. If it isn't, the ticket was usually the problem, not the agent.

That's the lever. The more I trusted my own ticket description, the less I watched. A ticket that says what done looks like and what's out of scope gets a PR I can skim. A vague one gets a PR I have to read line by line, which is slower than writing the code myself.

The hand-back is the agent's job too. It writes the PR description, and its commits follow my conventional-commits format with the ticket number in the scope. Because of that, Clocktopus links every commit, review and agent session to the right ticket without me touching a form.

Run reviews after hours

For the PRs I was less sure about, I had an agent review them. The first time I did that during working hours. Don't.

Code review burns tokens, even at medium effort. The reviewer reads the diff, then everything the diff touches, and then argues with itself about what it found. On the 5x Max plan I hit the quota twice that week, and both times it was a review I could have queued for the evening. If a PR isn't blocking anyone, let the review run overnight and read the findings with your coffee.

Know when a thread goes idle

Here's the trade-off I haven't solved. Zed's agent threads tell you when an agent has stopped. The terminal doesn't.

I left the threads because the output is too noisy to follow. Every command the agent runs is printed in full, and I don't want to read them. If the harness has decided a command is safe, I trust it, especially with a frontier model driving. What I want is the diff, and a nudge when it's done.

So mid-week I was back in the terminal, still using Zed's workspaces to jump between worktrees, and with no idle signal at all. I'm sure plenty of small tasks sat finished for a long time before I got to them. Still a good week. But tools like Herdr and T3 Code keep every thread visible without switching workspace, and I reckon that would have shaved real idle time off. I'll give them a go and report back.

The numbers

Everything above is anecdote until you measure it. These are the week's figures as Clocktopus recorded them, from git activity and agent telemetry, with no timesheet involved. The hours view first: my tracked time per day, agent runtime on its own line so the two are never added together, and the PRs merged each day on top.

Hours per day for the week: 34.27 hours tracked over six active days, with agent runtime on its own line and the PRs merged each day

Measure Week
Pull requests merged 45
Commits 156
Hours of me steering 34
Hours of agents running 15
Tokens 832M
What that would cost at API pricing US$909

Delivery for the week: 45 merged, 100% merge rate, and the work complexity split between quick wins, bulk changes and heavy lifts

The delivery view adds a detail I didn't expect. Of the 52 PRs opened, 23 were quick wins and 22 were bulk changes, with only 6 heavy lifts. Worktrees didn't make me write harder code. They let me keep a lot of small, well-scoped changes moving at once, which is exactly what a good ticket produces.

Two things the headline hides. The work wasn't the same shape from one week to the next: the complexity split above is this week's, and the 8-PR week had a different mix, so 8 to 45 isn't a like-for-like jump. And the product owners were available. Every time a ticket hit a fork, I could get a decision in minutes instead of parking the thread until the next meeting. That made more difference than any tool. A worktree that's waiting on a human is just as idle as one that's waiting on me.

The point of measuring isn't the headline number. It's that every habit above has a number attached: the setup time before a thread can start, the tokens a review costs, the gap between an agent finishing and me noticing. Change one thing, watch the number, keep it or drop it.

How's your team doing with agents? If the honest answer is "not sure", that's the first bottleneck to fix. Measure it first. Then change one thing and tell me how the numbers moved.

Start measuring what your team ships

Output, cost and what your agents burn. Read from the commits, pull requests and agent runs you already have.

Start free

Free for single developers.