For a long time I used Claude Code the obvious way. One session. One task at a time. Type something, wait, read the output, type the next thing. It felt productive because I was shipping, but I kept hitting the same wall: most of the day, I was waiting.

Then I started using subagents properly and it stopped feeling like waiting. It started feeling like I had three or four junior devs all doing different things while I actually thought about the problem. Which is, honestly, how it should’ve felt from day one.

This is the workflow I’ve landed on. It’s not fancy. It just respects the fact that most dev work is a bunch of independent things pretending to be one big task.


What a subagent actually is

A subagent is just another Claude Code instance that your main session can spin up to do a chunk of work. It runs on its own, doesn’t clog up the main conversation, and reports back when it’s done. That’s the whole idea.

The trap is thinking of it as “Claude but smaller.” It’s not smaller. It’s a fresh context that only knows what you tell it. That’s actually the point. The main session stays focused on the thing you care about, and the grunt work gets handed off.

I resisted using subagents for weeks because I thought it was overkill. It wasn’t. I was just stubborn.


The first time it clicked

I was migrating a Next.js codebase from the pages router to the app router. Classic miserable task. Hundreds of files, most of them doing similar things with enough variation that you can’t just run a script.

My first approach: one Claude Code session, walk through each file, do the migration, move on. Two hours in, the context was full of half-finished migrations and I was losing track of what was done.

Second approach: I told the main session to spin up a subagent for each major route group. One subagent for /dashboard, one for /settings, one for /admin. Each one got clear instructions, the migration guide, and a list of files. They worked in parallel. I reviewed the output.

Spawn a subagent to migrate everything under src/app/dashboard to the app router. Follow the conventions already used in src/app/(marketing). Report back with a list of files changed and any blockers.

Done in 40 minutes. I wasn’t faster at typing. I just wasn’t the bottleneck anymore.


When I use subagents now

Three situations, pretty much always.

Research that bloats context. If I need to read 20 files to figure out where something lives, I send a subagent. It reports back with the answer and the main session never has to load all that code. Keeps my main context clean for the work that matters.

Search the codebase and tell me every place that calls the Stripe API. Return file paths, line numbers, and a one-sentence summary of what each call does.

Independent chunks of the same task. Writing tests for five different modules? Five subagents. Running the same refactor across a few directories? One subagent per directory. They don’t need to know about each other.

Things that take a while but don’t need my brain. Generating docs, migrating configs, running a big search-and-verify. I kick off a subagent and go back to the real work.


What I always include in the prompt

I wasted a lot of time early on by giving subagents vague instructions. A subagent with no context is a subagent that invents its own context, and the output reflects that.

Here’s the shape I use now:

Task: [one sentence, specific]
Relevant files: [exact paths]
Conventions to follow: [point to an existing file or pattern]
Report back with: [what I need to see to trust the result]

That last line is the one everyone skips. Without it, the subagent either over-reports (dumping 400 lines of output) or under-reports (“done”). Both are useless.

A real example from last week:

Task: Add zod validation to every route handler in src/app/api.
Relevant files: all files in src/app/api/**/route.ts.
Conventions: follow the pattern already used in src/app/api/users/route.ts.
Report back with: the list of routes modified, and any routes where the input shape wasn't clear enough to validate.

The “any routes where the input shape wasn’t clear” bit is gold. That’s where the real bugs hide, and the subagent surfaces them instead of silently making something up.


The thing nobody warns you about

Subagents are not free. Each one burns tokens. Each one can also produce output that’s technically correct but stylistically off from the rest of your codebase. If you spawn ten of them with loose instructions, you’ll spend more time cleaning up than you saved.

I’ve had subagents rewrite import order for no reason. Rename variables I wanted to keep. Add comments I didn’t ask for. The fix is always the same: tighter prompts, specific constraints, pointers to existing patterns.

Also: don’t run subagents for tasks that need your main session’s context. If the work depends on the conversation we’ve been having, the subagent doesn’t have that context and will drift. Keep subagents for self-contained chunks.


How I think about it now

Before subagents, my mental model was “me plus Claude Code.” Single-threaded. One of us was always waiting on the other.

Now it’s more like “me plus a team.” The main session is the lead engineer I pair with on the hard stuff. The subagents are the extra hands I send off to do the parts I could do myself if I had three more hours in the day.

The work doesn’t actually get done faster in absolute terms. It gets done faster in my terms because I’m not the bottleneck on everything anymore. That difference is bigger than it sounds.


A small warning

Don’t spawn subagents just because you can. I went through a phase where I’d send off three subagents for everything and half of them came back with output I had to throw away. The good use cases are real. The “look at all my parallel agents” use cases are a waste.

If you can do the task yourself in two minutes, do it yourself. If it’s going to take twenty minutes of typing and reading, send a subagent. That’s the whole rule.


Subagents aren’t magic. They’re just the difference between using Claude Code like a chatbot and using it like a team. Once I made that switch, I stopped dreading the big, boring migrations and started handing them off. That’s the part nobody tells you. It’s not about speed. It’s about not being the one who has to hold the whole thing in your head.