You’re building a CrewAI crew and the documentation mentions two process types: sequential and hierarchical. The sequential process is straightforward — tasks run in order, each agent hands off to the next. But crewai when to use hierarchical process isn’t always obvious from the docs. The short answer: reach for hierarchical when you have a coordinator agent that should decompose a goal into subtasks, assign them to specialists, and synthesize results — especially when the task graph isn’t known upfront. This guide walks through the decision criteria, implementation patterns, and the tradeoffs you’ll hit in production.
Understanding the two processes
CrewAI ships with two built-in process classes. SequentialProcess executes tasks in the order you define them. Each task’s output becomes context for the next. HierarchicalProcess introduces a manager agent that plans, delegates, and aggregates. The manager doesn’t just pass context — it decides which specialist handles each piece of work, potentially in parallel, and can iterate based on intermediate results.
from crewai import Crew, Process
# Sequential: you define the exact chain
crew = Crew(
agents=[researcher, writer, editor],
tasks=[research_task, write_task, edit_task],
process=Process.sequential
)
# Hierarchical: manager decides the plan
crew = Crew(
agents=[manager, researcher, writer, editor],
tasks=[research_task, write_task, edit_task],
process=Process.hierarchical,
manager_llm=llm # required for hierarchical
)
The manager agent needs its own LLM (via manager_llm or manager_agent) because it’s doing reasoning: task decomposition, agent selection, and result synthesis. This is the first cost signal — you’re paying for an additional reasoning loop on every run.
When hierarchical makes sense
Unknown or dynamic task graphs
If you can’t enumerate the exact sequence of steps before runtime, hierarchical shines. A classic example: a research crew where the manager decides how many sources to pull, whether to pursue tangents, and when enough evidence exists.
manager = Agent(
role="Research Director",
goal="Answer the user's question thoroughly by delegating to specialists",
backstory="You break down complex questions, assign researchers, and synthesize findings.",
llm=llm,
allow_delegation=True # critical for hierarchical
)
researcher = Agent(
role="Subject Matter Researcher",
goal="Find authoritative sources on assigned subtopics",
backstory="You dig deep into specific topics and return cited evidence.",
llm=llm,
allow_delegation=False
)
The manager might spawn three researcher tasks for a broad query, or just one for a narrow one. Sequential can’t do this without hardcoding every branch.
Specialists with non-overlapping expertise
When agents have genuinely different toolsets or knowledge bases, a manager that routes correctly beats a fixed pipeline. Example: a code generation crew where one agent writes Python, another writes SQL, another writes Terraform. The manager reads the spec and routes each component to the right specialist.
python_dev = Agent(role="Python Developer", tools=[python_repl], allow_delegation=False)
sql_dev = Agent(role="SQL Developer", tools=[sql_executor], allow_delegation=False)
infra_dev = Agent(role="Infrastructure Engineer", tools=[terraform_cli], allow_delegation=False)
manager = Agent(
role="Tech Lead",
goal="Decompose the feature spec and assign components to the right specialist",
llm=llm,
allow_delegation=True
)
Iterative refinement loops
Hierarchical processes can implement “review → revise” cycles that sequential processes struggle with. The manager evaluates a specialist’s output, decides if it meets quality bars, and either accepts it or delegates a revision task with specific feedback.
# Manager's reasoning (simplified) in its system prompt:
"""
When reviewing deliverables:
1. Check against acceptance criteria
2. If gaps exist, delegate a revision task to the same specialist with specific feedback
3. Maximum 2 revision cycles per deliverable
4. Then escalate to human if still failing
"""
This pattern is common in content pipelines (draft → edit → polish) and code review flows.
When sequential is the right call
Fixed, known workflows
If your process is always A → B → C with no branching, sequential is simpler, cheaper, and more predictable. No manager LLM call, no delegation overhead, easier debugging.
# This is fine for sequential
tasks = [
Task(description="Extract entities from document", agent=extractor),
Task(description="Classify entities by type", agent=classifier),
Task(description="Write structured output", agent=formatter)
]
Latency-sensitive paths
Hierarchical adds at least one extra LLM round-trip (the manager’s planning step) and often more (delegation decisions, synthesis). If you’re serving user-facing requests with sub-second SLAs, sequential’s deterministic latency is a feature.
Debugging and observability matter
With sequential, the execution trace is the task list. With hierarchical, you need to log the manager’s decisions, which agents were invoked, in what order, and why. If your team doesn’t have tracing infrastructure yet, sequential buys you time.
Implementing hierarchical correctly
Give the manager a tight system prompt
The manager’s behavior lives in its backstory and goal fields — these become the system prompt. Be specific about delegation rules, quality bars, and stopping conditions.
manager = Agent(
role="Project Coordinator",
goal=(
"Decompose the user request into discrete tasks, assign each to the "
"appropriate specialist, and synthesize a final answer. "
"Never attempt to do specialist work yourself."
),
backstory=(
"You are an experienced technical lead. You know which specialist handles "
"which domain. You delegate aggressively but verify results. "
"Rules: (1) Max 3 concurrent delegations. (2) Require citations from researchers. "
"(3) Reject vague outputs — demand specifics. (4) Stop when all acceptance criteria are met."
),
llm=llm,
allow_delegation=True,
max_iter=5 # prevent infinite delegation loops
)
Constrain delegation with max_iter and max_rpm
max_iter on the manager limits how many delegation cycles it can run. max_rpm (requests per minute) on the crew prevents runaway API costs. Both are guardrails you’ll regret missing.
crew = Crew(
agents=[manager, researcher, writer, editor],
tasks=[research_task, write_task, edit_task],
process=Process.hierarchical,
manager_llm=llm,
max_iter=6, # manager stops after 6 delegation cycles
max_rpm=30, # rate limit across all agents
verbose=True
)
Design tasks for delegation, not execution
In hierarchical crews, tasks describe what needs doing, not how. The manager decides the how. Write task descriptions that are outcome-oriented and include acceptance criteria.
research_task = Task(
description=(
"Research the competitive landscape for {product_category}. "
"Deliverable: a markdown table with columns: Competitor, Key Features, "
"Pricing, Target Market, Differentiators. Minimum 5 competitors. "
"Every claim must include a source URL."
),
agent=researcher, # this is the *default* agent; manager can override
expected_output="Markdown table with 5+ competitors and cited sources"
)
The agent field here is a hint — the manager can reassign. The expected_output is the contract the manager verifies against.
Common pitfalls
The manager does the work instead of delegating
If your manager’s backstory says “you are an expert researcher,” it will research. Explicitly forbid this.
# Bad
backstory="You are an expert researcher who delegates when busy."
# Good
backstory="You NEVER do research yourself. You ONLY plan, delegate, and synthesize."
Unbounded delegation loops
Without max_iter or clear stopping criteria in the manager prompt, the crew can spin indefinitely: delegate → review → reject → delegate → review → reject. Set both a hard limit (max_iter) and a soft rule in the prompt (“maximum 2 revisions per deliverable”).
Context window explosion
Each delegation round adds the specialist’s full output to the manager’s context. With verbose specialists and multiple rounds, you’ll hit token limits. Mitigations:
- Instruct specialists to return concise, structured outputs (JSON, tables)
- Use
contextparameter on tasks to limit what the manager sees - Implement summarization tasks for long-running crews
# Limit context passed to manager
research_task = Task(
description="...",
agent=researcher,
context=[previous_summary_task] # only the summary, not full history
)
Silent failures when specialists hallucinate
The manager evaluates outputs against expected_output, but it’s an LLM judging an LLM. Add deterministic validation where possible.
from crewai import Task
import json
def validate_competitor_table(output: str) -> bool:
try:
data = json.loads(output) if output.strip().startswith('[') else None
if not data or not isinstance(data, list):
return False
required = {"competitor", "features", "pricing", "market", "differentiators"}
return all(required.issubset(set(row.keys())) for row in data)
except Exception:
return False
research_task = Task(
description="...",
agent=researcher,
expected_output="Valid JSON array of competitor objects",
callback=validate_competitor_table # runs after agent completes
)
Tradeoffs at a glance
| Dimension | Sequential | Hierarchical |
|---|---|---|
| Predictability | High — fixed order | Variable — manager decides |
| Latency | Lower (no planning step) | Higher (manager + delegation rounds) |
| Cost | Fixed per run | Variable — depends on delegation depth |
| Flexibility | Low — code changes for new flows | High — manager adapts to novel requests |
| Debugging | Trivial — read the task list | Hard — need manager decision logs |
| Best for | Pipelines, ETL, fixed workflows | Open-ended problems, routing, review loops |
A decision checklist
Before committing to hierarchical, ask:
- Can I write down the exact task sequence for every possible input? If yes → sequential.
- Do I need different specialists for different input types? If yes → hierarchical.
- Is there a review/revise cycle that varies per run? If yes → hierarchical.
- Can I tolerate 2-5x latency and cost variance? If no → sequential.
- Do I have observability for manager decisions (logs, traces)? If no → build that first, or use sequential.
- Can I define clear stopping criteria for the manager? If no → sequential until you can.
Production pattern: hybrid crews
You don’t have to choose one process for the entire system. A common pattern: hierarchical at the top level for planning and routing, sequential sub-crews for well-understood pipelines.
# Top-level: hierarchical planner
planner_crew = Crew(
agents=[planner, researcher, coder, tester],
tasks=[plan_task, research_task, code_task, test_task],
process=Process.hierarchical,
manager_llm=llm
)
# Inside code_task: a sequential sub-crew for the actual implementation
def execute_code_plan(plan: str) -> str:
impl_crew = Crew(
agents=[architect, backend_dev, frontend_dev, devops],
tasks=[arch_task, backend_task, frontend_task, deploy_task],
process=Process.sequential
)
return impl_crew.kickoff(inputs={"plan": plan})
code_task = Task(
description="Implement the approved plan using the implementation crew",
agent=coder,
expected_output="Deployed feature with passing tests",
callback=execute_code_plan # runs sequential crew internally
)
This gives you adaptive planning where it matters and deterministic execution where the path is known.
Final thoughts
Hierarchical process in CrewAI is a power tool — it lets you build crews that handle genuinely open-ended requests. But it introduces nondeterminism, latency variance, and debugging complexity that sequential process avoids. Start with sequential. Move to hierarchical when you have a concrete need: dynamic routing, iterative refinement, or unknown task graphs. And when you do, constrain the manager aggressively — tight prompts, max_iter, validation callbacks, and observability from day one.
If you’re running these crews at scale and need consistent model access across providers with automatic fallback and usage metering, n4n.ai’s OpenAI-compatible endpoint lets you swap models without rewriting crew configurations — useful when a specialist agent needs a different capability profile mid-run.