{"slug": "crewai-s-quadratic-context-problem-why-a-5-agent-crew-costs-6-more-than-you", "title": "CrewAI's quadratic context problem: why a 5-agent crew costs 6 more than you expect", "summary": "CrewAI's default context-passing model causes a quadratic token cost curve, where a 5-agent crew costs up to 6× more in input tokens than a solo agent, and with memory and verbose mode it can climb to 8–15×. The framework sequentially accumulates all prior task outputs into each subsequent agent's prompt without summarization or caching, leading to rapidly escalating API costs. A developer audit shows that for five tasks with moderate outputs, total input tokens reach 9,000 versus a naive estimate of 4,000, and scaling to larger outputs yields 24,000 input tokens—6× the expected amount.", "body_md": "*Cost-audit series, episode 3. This series began with an AI agent that burned 136M tokens overnight →.*\n\nCrewAI is one of the most-starred agent orchestration frameworks on GitHub. Its pitch is intuitive: define a crew of role-playing agents, assign tasks, watch them collaborate. What the README doesn't tell you is that the default context-passing model has a **quadratic token cost curve**. A 5-agent crew doesn't cost 5× a solo agent — on input tokens it costs closer to 6×, and once you stack memory, delegation, and verbose mode it climbs to 8–15×. The multiplier grows with every agent or task you add.\n\nThis audit shows you exactly where the tokens go, with line numbers.\n\nCrewAI executes tasks sequentially (by default). Each task has an optional `context`\n\nlist — a list of other tasks whose outputs should be available to the executing agent. When you don't specify `context`\n\nexplicitly, CrewAI's default behavior is to make all *previously completed tasks* available to each subsequent agent. The output of Task 1 goes into Task 2's prompt. Task 1 + Task 2 outputs go into Task 3's prompt. And so on.\n\nThis is linear accumulation — and it produces a quadratic total token count.\n\n** src/crewai/crew.py** — the\n\n`Crew._get_context`\n\nmethod (line 792 at tag 0.80.0):\n\n``` python\ndef _get_context(self, task: Task, task_outputs: List[TaskOutput]):\n    context = (\n        aggregate_raw_outputs_from_tasks(task.context)\n        if task.context\n        else aggregate_raw_outputs_from_task_outputs(task_outputs)\n    )\n    return context\n```\n\nSource: `src/crewai/crew.py#L792`\n\nThe decisive branch is the `else`\n\n: when a task sets **no explicit context**, CrewAI falls back to\n\n`aggregate_raw_outputs_from_task_outputs(task_outputs)`\n\n— the outputs of `crewai/utilities`\n\n) serializes each prior task's full raw output into the string that gets injected into the current task's prompt. There is no summarization, no truncation, no deduplication. The string grows with every task.** src/crewai/crew.py** — the task execution loop lives in\n\n`Crew._execute_tasks`\n\n(defined at line 635 at tag 0.80.0; the context-injection call is at line 696). Simplified to the two lines that matter:\n\n```\n# inside _execute_tasks, iterating over the crew's tasks:\ncontext = self._get_context(task, task_outputs)   # task_outputs = every prior task's output\ntask_output = task.execute_sync(\n    agent=agent_to_use, context=context, tools=agent_to_use.tools\n)\n```\n\nSource: [ src/crewai/crew.py](https://github.com/crewAIInc/crewAI/blob/0.80.0/src/crewai/crew.py) (method\n\n`_execute_tasks`\n\n)`task_outputs`\n\nis the running list of every prior task's output, so it grows as the crew progresses. Each call to `execute_sync`\n\nconstructs a full prompt that includes that accumulated context string, and it is sent with **every** LLM API request — not cached between tasks (CrewAI doesn't use prompt caching by default).\n\nAssume:\n\nToken count for Task k = T_system + (k-1) × T_task (accumulated context from all prior tasks)\n\n| Task | Context tokens | System + task | Total input tokens |\n|---|---|---|---|\n| 1 | 0 | 800 | 800 |\n| 2 | 500 | 800 | 1,300 |\n| 3 | 1,000 | 800 | 1,800 |\n| 4 | 1,500 | 800 | 2,300 |\n| 5 | 2,000 | 800 | 2,800 |\nTotal |\n5,000 |\n4,000 |\n9,000 |\n\nA naive model would predict 5 × 800 = 4,000 input tokens. The actual bill is **9,000** — 2.25× for just five tasks with modest outputs. Now scale up:\n\n| Task | Context tokens | System + task | Total input tokens |\n|---|---|---|---|\n| 1 | 0 | 800 | 800 |\n| 2 | 2,000 | 800 | 2,800 |\n| 3 | 4,000 | 800 | 4,800 |\n| 4 | 6,000 | 800 | 6,800 |\n| 5 | 8,000 | 800 | 8,800 |\nTotal |\n20,000 |\n4,000 |\n24,000 |\n\nNow you're at **6×** the naive estimate — and that's *input tokens only*. Add output tokens from each task (another ~2,000 × 5 = 10,000) and the total API cost for one crew run is 34,000 tokens instead of the ~14,000 you'd expect.\n\nWith claude-sonnet-4-6 ($3/M input, $15/M output):\n\nNow run 50 crew executions per day:\n\nFor a SaaS product with hundreds of daily crew runs, this gap becomes tens of thousands of dollars per month — and it gets worse as you add agents or as task outputs grow.\n\nCrewAI's `memory=True`\n\nflag (off by default, but heavily promoted) activates four memory systems:\n\n```\n# src/crewai/memory/short_term/short_term_memory.py\nclass ShortTermMemory(Memory):\n    def search(self, query: str, score_threshold: float = 0.35):\n        return self.storage.search(query=query, score_threshold=score_threshold)\n```\n\nSource: `src/crewai/memory/short_term/short_term_memory.py`\n\nShort-term memory retrieves every stored item scoring above a similarity threshold (default `0.35`\n\n) and appends them to the prompt — the count is unbounded, so a longer run history injects more retrieved context per task. Long-term memory hits an SQLite database. Entity memory maintains structured entity descriptions. Semantic memory uses ChromaDB embeddings — each retrieval costs an embedding API call *plus* the tokens from the retrieved chunks injected into the prompt.\n\nWith `memory=True`\n\non a 10-run crew history, expect **+1,500–3,000 tokens per task** in retrieval overhead.\n\n`verbose=True`\n\n(the default in most tutorials)\nMost CrewAI tutorials set `verbose=True`\n\nor `verbose=2`\n\n. This surfaces the agent's intermediate reasoning — but the real cost driver isn't the logging, it's the ReAct loop underneath it. CrewAI runs its own `CrewAgentExecutor`\n\n(not LangChain's), and each agent step accumulates the full \"Thought / Action / Observation\" trace back into the LLM prompt for the next iteration. Each tool call adds another round of Thought + Action + Observation tokens before the final answer. For an agent that calls 3 tools, this can add **800–2,000 tokens** per task.\n\n`allow_delegation=True`\n\n)\nWhen an agent can delegate to another, it can route subtasks to specialist agents mid-task. This is CrewAI's \"hierarchical\" feature. The cost: each delegation creates **a new complete LLM call** with the delegating agent's accumulated context inherited into the delegatee's prompt. A single task can spawn 2–3 delegation chains, each carrying the full context blob from above.\n\nLet's measure a concrete 3-agent research crew using `@wartzar-bee/tokenscope`\n\n:\n\n```\nnpx @wartzar-bee/tokenscope crew-session.jsonl\n```\n\nFor a crew with:\n\nThe per-agent context accumulation (illustrative — tokenscope reports the session total you can check this against, not a per-agent split):\n\n```\nPer-agent context accumulation:\n  researcher  →  input:  1,100  output:  1,800   (system + task only)\n  analyst     →  input:  2,900  output:  1,200   (+1,800 context from researcher)\n  writer      →  input:  4,100  output:  2,000   (+1,800 + 1,200 context from prior two)\n\n  Total input:    8,100\n  Total output:   5,000\n  Session total: 13,100 tokens\n\n  Naive estimate (no context accumulation): 8,300 tokens\n  Actual multiplier: 1.58×\n```\n\nThis is a *modest* crew. Bump to 5 agents with research-heavy outputs and the multiplier reaches 4–6×. Add memory and delegation: 8–15×.\n\nCrewAI lets you control which tasks feed context to which. Use the `context`\n\nparameter explicitly:\n\n``` python\nfrom crewai import Task\n\nresearch_task = Task(\n    description=\"Find the top 3 cloud cost optimization techniques.\",\n    agent=researcher,\n    # no context — this is the first task\n)\n\nanalysis_task = Task(\n    description=\"Analyze the techniques and rank by ROI.\",\n    agent=analyst,\n    context=[research_task],  # only research output, not all prior tasks\n)\n\nwriting_task = Task(\n    description=\"Write a 500-word summary of the #1 technique.\",\n    agent=writer,\n    context=[analysis_task],  # only the analysis — researcher output not needed here\n)\n```\n\nResult: the writer agent sees only the analyst's output (~1,200 tokens), not the researcher's raw output + the analyst's output (3,000 tokens). Context tokens halved on the most expensive task.\n\nFor longer pipelines, consider a **summary task**: a cheap, short-output task that condenses prior results, and only *its* output flows forward. The cost of the summarization step is far less than sending raw outputs through N subsequent agents.\n\nIf you're running CrewAI in production, the default LLM logging doesn't surface how much of each call is re-sent accumulated context. Point tokenscope at a session transcript to see it:\n\n```\nnpm install -g @wartzar-bee/tokenscope\n```\n\nExport your run as a session JSONL (a Claude Code session under `~/.claude/projects`\n\n, or any transcript in that format), then:\n\n```\nnpx @wartzar-bee/tokenscope crew-session.jsonl\n# machine-readable:\nnpx @wartzar-bee/tokenscope crew-session.jsonl --json\n```\n\nYou'll see the session total, how much is new work versus re-sent accumulated context, and where the growth is steepest — the accumulation this whole post is about.\n\nCrewAI's default context model accumulates all prior task outputs into every subsequent agent's prompt. This produces a quadratic total token count as N grows — not linear. The practical impact at modest scale (5 agents, 2,000-token outputs): **4–6× the token count you'd expect**. Add memory layers, delegation, and verbose mode: **8–15×**.\n\nThe fix is explicit context scoping: pass only the task outputs that each agent actually needs. It's a one-line change per task, and it can halve your API bill immediately.\n\n**Next in the series:** we'll look at LangGraph's token footprint — the stateful graph model has a different cost shape, and it's worth understanding before you migrate from LangChain to LangGraph chasing efficiency gains.\n\n*wartzar-bee builds tools for operating cost-efficient autonomous agents. tokenscope is free and open-source. Follow on dev.to →*", "url": "https://wpnews.pro/news/crewai-s-quadratic-context-problem-why-a-5-agent-crew-costs-6-more-than-you", "canonical_source": "https://dev.to/wartzarbee/crewais-quadratic-context-problem-why-a-5-agent-crew-costs-6x-more-than-you-expect-3ol1", "published_at": "2026-07-26 03:55:49+00:00", "updated_at": "2026-07-26 04:58:16.398861+00:00", "lang": "en", "topics": ["artificial-intelligence", "ai-agents", "developer-tools", "large-language-models", "ai-infrastructure"], "entities": ["CrewAI", "claude-sonnet-4-6"], "alternates": {"html": "https://wpnews.pro/news/crewai-s-quadratic-context-problem-why-a-5-agent-crew-costs-6-more-than-you", "markdown": "https://wpnews.pro/news/crewai-s-quadratic-context-problem-why-a-5-agent-crew-costs-6-more-than-you.md", "text": "https://wpnews.pro/news/crewai-s-quadratic-context-problem-why-a-5-agent-crew-costs-6-more-than-you.txt", "jsonld": "https://wpnews.pro/news/crewai-s-quadratic-context-problem-why-a-5-agent-crew-costs-6-more-than-you.jsonld"}}