Claude Code offers two main patterns for multi-step work: subagents (spawned via the Task tool, where Claude orchestrates dynamically) and dynamic workflows (a JavaScript script Claude writes that can run up to 1,000 parallel agents while keeping your context window clean). The decision comes down to two questions: who holds the plan, and how many context windows the task actually needs.
I've been running both patterns in production for months. The choice isn't about which is "better" -- it's about matching the pattern to the task. Get it wrong and you either burn 7x the tokens you need to, or you fail to parallelize work that should never run sequentially.
What's the actual difference between subagents and dynamic workflows?
The core difference is where the orchestration logic lives. With subagents, Claude IS the orchestrator -- it decides turn by turn what to spawn next, every result lands in the parent context window, and Claude reasons about intermediate output before spawning the next task. With dynamic workflows, a JavaScript script is the orchestrator -- Claude writes the script, the runtime executes it in the background, and Claude's context holds only the final verified answer.
Subagents work through the Task tool. Your main Claude instance spawns separate Claude Code instances, each with their own system prompt, context window, and tool access. The parent session coordinates them and sees all their outputs. Dynamic workflows invoke the Workflow tool: Claude writes a JavaScript orchestration script that uses three primitives -- agent(), pipeline(), and parallel() -- to manage potentially hundreds of agents. According to the Claude Code documentation, workflows run up to 16 agents concurrently with a hard cap of 1,000 agents per workflow run.
One other key distinction: nested subagents now support depth=5 as of v2.1.172 (June 9, 2026). Subagents can spawn their own subagents five levels deep, which is useful for hierarchical tasks. But as the token math section shows, depth beyond 3 gets expensive fast.
When do subagents win?
Subagents are the right call when Claude needs to make orchestration decisions dynamically based on what each step returns. If the next task can't be planned in advance -- because it depends on reasoning about what the last step found -- you want Claude in the loop between steps, not code. Subagents are also the simpler setup for shallow fan-outs: 2-5 parallel tasks that each need their own context window where the parent synthesizes everything without drowning.
Concrete examples where subagents win:
- Debugging a failing CI pipeline. You don't know where the failure is yet. Claude needs to run a test, see what breaks, decide what to look at next, spawn a subagent to dig into that specific module, and adapt based on what it finds. The path is unknown; Claude must navigate it.
- Competitive research with unknown scope. Start by searching a competitor's feature list. Depending on what's there, spawn subagents to dig into pricing, or their API docs, or their recent changelog. The research tree branches based on what Claude finds.
- Code review with feedback loops. A subagent reviews a file and flags issues. The parent decides whether to spawn a follow-up subagent to propose fixes or to escalate certain findings. Judgment calls at each step.
The sweet spot is depth 2-3. At depth 2, you have a parent orchestrating 3-10 specialized subagents. At depth 3, each of those spawns 2-5 more. Beyond that, the context overhead starts eating the gains.
When do dynamic workflows win?
Dynamic workflows win when the task structure is known upfront and can be expressed as code. If you can write a list of items and a set of stages to run each item through, you want a workflow -- not Claude making decisions turn by turn. The orchestration becomes deterministic code rather than model reasoning, which means it's faster, cheaper, and resumable if it fails mid-run.
The most striking real-world example: Bun creator Jarred Sumner used Claude Code dynamic workflows to port Bun from Zig to Rust, writing approximately 750,000 lines of Rust in 6 days with hundreds of agents working in parallel and two independent reviewers on each file. No single-session subagent tree could hold that scale -- the work list was too large, the parallelism too deep. A workflow script drove the whole operation.
Concrete examples where workflows win:
- Audit 500 files for a specific pattern. The work list is the file list. Fan it out with
pipeline(files, checkFile, verifyFinding) and get all results without any intermediate output landing in your context window.
- Generate a batch of 30 articles from a topic list. Each topic is independent. Write one script, run all 30 in parallel.
- Security audit across a monorepo. Find all API surface area, check each endpoint, adversarially verify each finding. Pipeline pattern with a verify stage after find.
- Large-scale code migration. Transform each file, run tests, verify each transform passes. Deterministic structure, known work list.
Want the templates from this tutorial?
I share every workflow, prompt, and template inside the free AI Creator Hub on Skool. 500+ builders sharing what actually works.
Join Free on Skool
The two-question decision framework
Two questions get you to the right pattern every time. First: who needs to hold the plan? If the orchestration logic can be expressed as deterministic code, use a dynamic workflow. If the orchestrator needs to reason about what to do next based on each intermediate result, use subagents. Second: how many context windows does the task need? If the work fits in a few isolated contexts that report to a single parent, subagents work fine. If the task needs 20, 50, or 500 parallel contexts, use a workflow script to manage them.
Quick cheat sheet:
- Known work list + same operation per item -- dynamic workflow, pipeline pattern
- Unknown work list, Claude decides what to tackle next -- subagents
- Need 15+ parallel agents -- dynamic workflow (subagent fan-out at that scale drowns the parent context)
- Need judgment calls mid-execution -- subagents
- Need to resume after failure -- dynamic workflow (workflows journal completed agent() calls; same script + same args returns cached results on resume)
- Simple 2-3 step delegation -- subagents, simpler to set up and debug
The token math: what each pattern actually costs
Token cost is the most underestimated variable when choosing between these patterns. Per Anthropic's cost management documentation, agent teams running in plan mode consume approximately 7x the tokens of a single-thread session. Subagent-heavy workflows add 200-500% overhead versus the same task run as a single agent. Running 10 agents in parallel costs roughly 10x what one sequential agent costs -- parallelism multiplies token consumption linearly.
Dynamic workflows shift this math by keeping intermediate results in JavaScript variables instead of Claude's context window. When an agent() call returns inside a workflow, the result lives in a variable -- not in the session's growing context. This avoids the exponential blowup that hits deep subagent trees, where every intermediate result stacks into an expanding parent context until it hits limits or costs spiral out.
Real-world calibration: one developer reported running 49 specialized subagents in parallel for 2.5 hours and received an estimated bill of $8,000-$15,000. That's the subagent pattern applied at workflow scale without workflow's context controls. The problem wasn't agents -- it was the wrong tool for that scale of fan-out.
On Claude Code Max ($100/month), dynamic workflows are included in the plan. The Workflow tool itself doesn't add per-token costs beyond what the individual agent() calls consume.
The three workflow primitives with real examples
Claude Code dynamic workflows ship with three core primitives that compose into every useful pattern. Claude writes the orchestration script based on your task description; you invoke it via the Workflow tool. Here's what each primitive does and when to reach for it, per the official workflow documentation:
agent(prompt, opts) spawns one subagent and returns its result. It's the atomic unit -- one isolated context window, one clean output. Everything else is built on top of this.
// Single agent -- simplest case
const result = await agent("Audit src/auth.ts for SQL injection patterns")
pipeline(items, stage1, stage2, ...) runs each item through every stage independently with no barrier between stages. Item A can be in stage 3 while item B is still in stage 1. This is the right default for multi-stage work -- fastest wall-clock time because nothing waits for the slowest item per stage to finish before the next stage starts.
// Audit all files, then verify each finding independently
const results = await pipeline(
files,
file => agent(`Audit ${file} for security issues`, {schema: FINDINGS_SCHEMA}),
findings => agent(`Adversarially verify these findings`, {schema: VERDICT_SCHEMA})
)
parallel(thunks) runs all tasks concurrently and waits for ALL to complete before moving on. Use this when you genuinely need all results before the next step -- for deduplicating findings across a full batch before running verification. It's a deliberate barrier; pipeline() is the leaner default when you don't need it.
// Fan out to multiple research angles, synthesize all at once
const research = await parallel([
() => agent("Search GitHub for MCP issues in the last 7 days"),
() => agent("Search Reddit for MCP discussions this week"),
() => agent("Search HackerNews for MCP threads this week")
])
const synthesis = await agent(`Synthesize: ${JSON.stringify(research)}`)
Version requirement: dynamic workflows need Claude Code v2.1.154 or later. Run claude --version to confirm you're on a compatible build before writing workflow scripts.
FAQ
Can I use dynamic workflows and subagents together in the same task?
Yes. Each agent() call inside a dynamic workflow IS a subagent -- it gets its own context window, system prompt, and tool access. You can configure custom agent types via the agentType option. The workflow script is the outer orchestrator; individual agent() calls are effectively subagents with isolated contexts, but their intermediate output doesn't accumulate in the parent session context.
What's the minimum Claude Code version for dynamic workflows?
Dynamic workflows require Claude Code v2.1.154 or later. The feature launched in May 2026 and is available on Pro, Max, Team, and Enterprise plans, as well as via direct API access on Amazon Bedrock, Google Vertex AI, and Microsoft Azure Foundry. Nested subagents at depth=5 require v2.1.172 specifically, which shipped June 9, 2026. Run claude --version to check.
How do I prevent runaway token costs with dynamic workflows?
Three controls work well together: prefer pipeline() over parallel() when you don't need a full result barrier (it's faster and uses less token overhead); scope each agent() prompt tightly so agents don't carry unnecessary context; and use the built-in budget global to set a hard ceiling -- while (budget.remaining() > 50_000) { ... } stops a discovery loop before costs escape. The 1,000-agent cap is a safety backstop, not a target to optimize toward.
When should I start with subagents and move to workflows later?
Start with subagents when the task structure is still unclear -- they're easier to set up and debug because Claude is making the orchestration decisions in real time. Once you understand the shape of the work (this list, these stages, this fan-out), encode it as a dynamic workflow. Workflows pay off when the structure is understood and the scale exceeds what a single parent context can manage cleanly.
Want the templates from this tutorial?
I share every workflow, prompt, and template inside the free AI Creator Hub on Skool. 500+ builders sharing what actually works.
Join Free on Skool