Skip to main content
Back to blogCopy Markdown
·10 min read
·claude codesubagentsskillsagentsios

Claude Code skills vs subagents: the shared simulator bug

Anthropic and an October paper question when subagents pay off. My case: parallel agents sharing one iOS simulator. When subagents still earn their place. →

Óscar Gallego

Software engineer · Málaga

Several separate workstations sharing a single device in the middle
On this page

Short answer: I’m keeping subagents, but I’m splitting work differently. Anthropic says to divide work by context, not by specialty, and an October paper finds that what breaks parallel subagents most is what they share. Mine broke on something as dumb as an iOS simulator. I now use subagents to read, search, and verify, and let them write in parallel only when each one has its own resources.

Nine days ago I wrote up how I hand Rydger stories to subagents. Rydger is my iOS and Android app for tracking car and motorcycle maintenance. Opus coordinates, Sonnet implements, every story gets its own worktree. Since then, two things have bugged me, both impressions I haven’t measured: it burns a lot of tokens, and most of the time the whole thing feels like a black box, with the work spread across contexts I never see.

This week, two pieces landed that seem to argue against that setup. An Anthropic post from October 22 makes the case for folding subagents into the main agent as skills and tools. And a paper, a preprint with one run per task, compares Codex, Claude Code, and Kimi Code with and without parallel subagents: on a 100-task sample of SWE-bench Verified, Claude Code drops from 83% to 59% when it’s allowed to spawn them.

Then there’s my own failure: Rydger’s UI tests kept failing for no reason whenever several agents ran them at once.

The random red tests came from one shared virtual iPhone

The simulator is the virtual iPhone Xcode runs UI tests on. Every worktree used the same one. Two xcodebuild runs on the same simulator corrupt its CoreData state, and perfectly good tests fail.

On top of that, when the simulator was shut down, xcodebuild booted it and shut it down again on every run. About 28 seconds each time.

The fix is one simulator per worktree, created on first use and left running. Rydger’s script does more, but the idea fits in a few lines:

# One simulator per worktree: created on first use, then left booted
name="Agent $(basename "$(git rev-parse --show-toplevel)")"
udid=$(xcrun simctl list devices available | grep -E "^ +$name \(" | grep -oE '[0-9A-F-]{36}' | head -1)
[ -n "$udid" ] || udid=$(xcrun simctl create "$name" "iPhone 17 Pro")
xcrun simctl bootstatus "$udid" -b >/dev/null
xcodebuild test -scheme MyApp -destination "id=$udid"

A second script for UI tests builds once and spreads the test classes across four of the worktree’s simulators, longest class first. Xcode’s own parallel testing option still took 615 seconds: it clones and boots fresh simulators on every run, and it queued both screenshot classes on the same one. The screenshot class, which was half the total time, is now two classes that run at the same time.

Since each worktree got its own simulator, I haven’t seen a false failure: all 35 UI tests passed five runs in a row, though I never wrote down how often they failed before. The table measures something else, speed, which comes mostly from not booting the simulator on every run and from spreading the classes:

RunBeforeAfter
UI tests (35 tests)1,062 s324–370 s
Full unit run47–52 s19–26 s
A single unit suite33 s8 s

No tests removed. The UI test time after the change varies by run, hence the range.

The time isn’t what bugs me. A red test stopped meaning “the code is wrong”, and an agent that sees a red test goes and fixes the code. Worktrees isolate files. Nothing else.

Anthropic keeps subagents and says to split by context

The version making the rounds is “one agent with skills beats an orchestrator with subagents.” The post is more careful than that, and worth reading in full before you delete anything.

It’s about agents built on Claude Platform for large companies, customer-facing ones, where every team ships its own subagent and a central team puts an orchestrator on top. Its examples are customer-facing enterprise agents, not coding agents. In those comparisons, a single agent with skills “frequently” came out ahead on quality, often at lower cost and latency. Frequently, not always.

It keeps subagents for three cases: when the main agent’s context gets bloated enough to hurt results, when parallel tasks need a fresh context you can throw away afterward, and when one agent can’t pick the right tool or has conflicting instructions. It also calls them effective for verification, parallel work, and splitting permissions.

The rule I’m taking away: if you split, split by context. Give each subagent a piece of work that needs little from the rest of the system and hands back a compact result. Split by problem type and you get what they call a telephone game, where every handoff loses fidelity. Give every team its own subagent and the architecture ends up as a copy of the org chart, Conway’s law applied to agents.

On context, my story split passes: a story is a chunk of work with a visible result, not “the iOS agent” and “the Android agent.” On shared resources it failed, and that rule wouldn’t have caught it.

The paper’s most common failure is shared state, and my simulator fits

The setup is fair: subagents weren’t forced. In concurrent mode each agent decided whether to spawn them; in sequential mode the delegation tools were turned off. 354 tasks, over 2,000 runs, and over $20,000 in API spend, with configurations frozen in July 2026. Claude Code ran Opus 5 and, in concurrent mode, ultracode with Dynamic Workflow, which isn’t quite the same as spawning subagents with the Agent tool. The authors limit their claims to those agents and benchmarks.

Claude Code’s 83% to 59% on SWE-bench Verified is the headline number, and its decline across all benchmarks combined is statistically significant. With subagents, token use runs 1.4 to 3.3 times that of sequential mode, and mean runtime goes up in 14 of 15 agent-benchmark pairs.

The paper’s conclusion is that subagents pay off more the longer the task, and that they should be turned on when needed, not by default. For Claude Code, the four long-horizon benchmarks are mixed: it improves on two and drops from 42.7% to 26.7% on RepoZero. My stories look more like a bounded SWE-bench task than building a whole repo, so I’m assuming the bad half of the headline applies to me.

The most useful part is their failure taxonomy. The biggest category, 33%, is shared state and merge: agents reading or modifying shared files or environments without coordinating. Lost global context is the smallest, 9%. A simulator several agents use at once fits that definition. The paper doesn’t classify iOS simulators, so the comparison is mine.

Cognition landed in a similar place in its April post: what works is several agents contributing intelligence while writes stay single-threaded.

The black box is two summaries per task

The subagents docs explain my other complaint. A subagent starts with a fresh, isolated context and doesn’t see the conversation. The main agent writes it a delegation message summarizing the task, and the subagent returns only a summary.

Whatever didn’t make it into the first summary, the subagent never learns. Whatever didn’t make it into the second, the main agent never sees. When something goes sideways, the full trace lives in the subagent’s context, not yours.

There’s one exception I hadn’t noticed: forks inherit the main conversation instead of starting fresh. For a task that leans on what you’ve already discussed, a fork loses less than a regular subagent.

And every subagent counts against your usage limit, even when its work ends up in the trash. I haven’t measured my own token spend, so I won’t claim savings.

Subagents read and verify; parallel writes only when nothing is shared

Here’s what I’ve already changed, merged in Rydger or already live in my skills:

  • One simulator per worktree and the UI test script described above. The script that removes a worktree also deletes its simulators.
  • A fixed test order in the testing skill: while iterating, swift test and only the suites the agent touched; the full unit suite once before each commit; UI tests once at merge.
  • One fewer handoff in my agent-team skill. A Haiku agent used to do the research and pass the facts to a Sonnet agent that implemented and re-checked them. Now the same agent researches and implements. Reviewers still run in parallel, but only one runs the tests; the rest just read.

And this is how I’m splitting work from now on:

  • Subagents to read. “Find every place this function is used and give me the list” is the textbook case: the subagent reads lots of files, I just get the list.
  • Subagents to verify. A reviewer with a clean context that never saw how the code was written.
  • Parallel writes only when nothing is shared. Files, branches, generated files, simulators, ports. If something is shared, I separate it first or run the work in series.
  • Team procedures in skills. What used to live in a specialist subagent’s prompt goes into a skill the main agent loads when it needs it.

One project and one simulator don’t settle anything

My case is one project and one shared resource: I parallelized without checking what my agents shared, and that doesn’t prove a single agent is better.

And removing subagents breaks things too. Anthropic’s example is a support agent with a shipping specialist: folding one subagent into another cut latency, but the agent started answering without asking that specialist for the delivery date. The failure only showed up in one of two runs, which is why they say to run every case more than once.

Start by listing what your agents share

Before you add or remove a subagent, write down what your agents use at the same time when they run in parallel: generated files, simulators, emulators, ports, local databases. Everything on that list needs its own copy per agent or has to run in series. That’s what I did, just later than I should have.

If you then want to drop a subagent, Anthropic suggests writing about ten end-to-end cases with the expected result first, running each one more than once with and without the subagent, and removing them one at a time. I haven’t done that yet. If the version without the subagent scores the same or better, it goes.

Sources

Related reading: how I hand stories to subagents and why your agent fails without a harness.


P.S. What were your parallel agents sharing that you hadn’t noticed? Tell me on LinkedIn.

Share this article

Related Posts