cat posts/2025-09-23-sub-agents-and-parallel-work.md
Sub-agents and parallel work
Last Thursday afternoon I had four terminal panes open, each with its own Claude Code session working on a different part of one feature, and I felt extremely productive for about forty minutes. Then two of them finished at once, a third asked me a question, and when I’d dealt with all that I found the fourth had spent twenty minutes “fixing” a test that the second one had just changed on purpose. I ended the day with less merged than if I’d done the whole thing with one agent and paid attention.
There are two different things people mean by parallel agents right now, and I’d been mixing them up, so it’s worth separating them.
The first is sub-agents inside one session. Claude Code added these at the end of July. You define a sub-agent in a Markdown file, with a description, its own instructions and its own list of allowed tools, and the main session can hand it a task. The important part is that the sub-agent gets its own context window. It goes off, reads thirty files, runs the tests, whatever it needs, and comes back with a summary, and only the summary goes into the main conversation. Before this, a long session would fill up with the contents of every file the agent had looked at, and by the second hour it had forgotten what we were doing. Now the searching happens somewhere else and the main thread stays short.
The second is several sessions at once, each doing its own piece of work. The usual way to do that is git worktrees, one checkout per agent on its own branch, so they’re not editing the same files on disk. That’s what I was doing on Thursday, and it’s the one that went badly.
Sub-agents have been an easy win, mostly. I have three I use all the time. One is a code searcher that can only read files and run grep, for “find everywhere we compute a renewal date”. One runs the test suite and reports only the failures, with the relevant lines, instead of four thousand lines of output. And one reviews a diff against a checklist I wrote, which is the sort of thing I’d once have done with a linter and a prayer. None of them can edit anything. That’s deliberate. Every time I’ve let a sub-agent write code, the main session has had to re-read what it wrote to understand it, and most of the saving disappears.
The parallel sessions are where I’ve had to learn things, and what I’ve learned is mostly things I already knew about people.
On Thursday’s feature, I split the work by layer: the database change, the API endpoints, the background job, and the front end. That’s how I’d have split it for four engineers, and it’s wrong for four engineers too, because every layer depends on the shape of the one below. The agent on the endpoints made an assumption about a column name, the agent on the database picked a different one, and both were reasonable. Four engineers would have talked to each other at standup. Four agents in four worktrees don’t talk at all, unless I carry messages, which is what I spent the afternoon doing.
What works better is splitting by things that really are independent. Last week I had three agents each upgrading a different internal tool, and that was close to three times as fast, because nothing they did touched anything the others did. The same goes for “write tests for these four modules” or “fix these five unrelated bugs from the backlog”. That kind of work splits cleanly. A feature, which is one idea spread across several files, mostly doesn’t.
The other limit is me. I can review roughly two streams of agent work at once without getting sloppy. At three I start skimming. At four I was approving things I hadn’t really read, which is the one thing I’ve been telling the team all year not to do. The agents aren’t the bottleneck. They finish whenever they finish, and then they sit there waiting for a person, and the person was me, tired, switching between panes.
Since August I’ve kept a column in my text file for whether a task ran alone or alongside others. Of the 41 tasks I ran in parallel, I merged 29 without major rework. For tasks I ran alone over the same weeks the rate was a bit higher, and it was a lot higher if you only count features. My sample isn’t big enough to be confident about the exact numbers, but the direction has been the same every week.
So the rules I’ve ended up with, for now:
- Sub-agents read and report. They don’t write.
- Parallel sessions only for work that shares no files and no assumptions.
- One spec per session, with its own definition of done, written before it starts.
- No more sessions than I can review properly, which for me is two, sometimes three.
- If two sessions need to agree on something, like a column name or an interface, I decide it first and put it in both specs.
None of that is new. It’s the same list I’d give a lead splitting work across a team. Fred Brooks wrote that adding people to a late project makes it later, and when I reread him in 2015 the part that held up best was the arithmetic: the pairs who might need to talk grow as n(n-1)/2, so four workers have six conversations to keep in sync, and with agents I’m the one having all six. Agents haven’t changed that. If anything they’ve made it easier to see, because an agent never pretends it was fine to skip the conversation. It just guesses, and the guesses don’t match.
The team has mostly arrived at the same place without my help. Two engineers tried a “swarm” setup on a feature last month, with an orchestrating agent handing pieces to five others, and they described the result as an impressive amount of code they then spent two days making consistent. Both are back to one main session with a couple of read-only helpers, plus parallel runs on the dull, separable stuff.
I’m keeping the four-pane layout, though. It’s very good for watching three upgrades and a test run at once, and it looks great on a screen share.