Subagents & Parallel Work

August 28, 2026 · View on GitHub

Kiro Crew can spawn background subagents to handle tasks in parallel. This is useful for fan-out work like reviewing multiple packages, running parallel searches, or delegating independent tasks.

How to Use

Via Chat

Ask naturally:

  • "Review these 3 packages in parallel"
  • "Search for X, Y, and Z at the same time"
  • "Run this task in the background"

Kiro Crew uses the spawn_run MCP tool to create subagents.

Via Slack

spawn review the latest CR for MyPackage
spawn list

The grammar is spawn <task> (or bg <task>) — there is no run subcommand; spawn list / spawn status render the running subagents.

Via MCP Tool

The spawn_run tool accepts:

  • task — single task description
  • tasks — array of tasks for parallel execution
  • agent / agents — optional agent name(s) for each task
  • include_memory / include_lessons / include_project — booleans (default true) switching off a context group the sub-agent would otherwise inherit
  • max_turns — per-spawn tool-call budget override (0 = unset, max 200)
  • model — model override for this spawn (e.g. deepseek-3.2)
  • reasoning_effortlow / medium / high / xhigh / max, batch-wide
  • keep — make the run a continuable conversation with guaranteed resumability and longer retention
  • cwd — absolute launch directory, which must be under a configured subagent_cwd_allowed_roots entry

Setting model or reasoning_effort, or keep: true, forces the dedicated-process path instead of session sharing.

The other spawn tools:

  • spawn_sub_agents — same fan-out as spawn_run, but BLOCKS and returns the collected results; takes agents (array of {agent_or_mode, prompt}), cwd, and the same include_* switches
  • spawn_continue — dispatch a follow-up turn into a completed run's conversation (conversation, task, optional agent / max_turns / model); context scope is inherited, so the include_* flags are not accepted
  • spawn_steer — inject a message into a RUNNING subagent's in-flight turn (agent_id, message, mode: interrupt default or follow_up)
  • spawn_release — end a continuable conversation (conversation) so it can no longer be continued
  • spawn_list — list running and completed subagents
  • spawn_status — read a completed run's retained transcript (see below)
  • resource_status — advisory host headroom (available memory, CPU load, posture, and the current concurrent sub-agent cap)

How It Works

  1. Kiro Crew spawns one or more subagent processes
  2. Each subagent gets its own agent session with full tool access
  3. Results are automatically injected back as [Subagent completion event]
  4. Kiro Crew synthesizes the results into a final response

Limits

  • Max concurrent: auto-sized at startup by default (agent.max_subagents = 0; floor 3, ceiling agent.subagent_auto_max = 32); set a positive integer to pin a fixed cap
  • Timeout: 30 minutes per subagent task (agent.subagent_timeout_secs), 20 minutes delivery (semaphore wait + injection), 15 minutes per injection attempt (KIROCREW_INJECTION_TIMEOUT, clamped to the delivery cap)
  • Turn limit: 100 turns per subagent (configurable via agent.subagent_max_turns, UI max 200)
  • Memory guard: spawns are refused when available memory drops below 4 GB (configurable via agent.spawn_min_memory_gb, set to 0 to disable)
  • No nesting: subagents cannot spawn their own subagents
  • Redaction: task strings in SubagentInfo are redacted (credentials + exfiltration URLs) before surfacing to Slack/dashboard

Named Agents

You can specify which agent a subagent should use:

spawn_run(tasks=["review code", "check tests"], agents=["code-reviewer", "test-analyzer"])

Named agents use their own system prompt and skills.

Results

Subagent results are posted to:

  • The dashboard (via WebSocket notification)
  • Slack DM (with an ack button)
  • The parent conversation (as completion events)

Long results are split into multiple Slack messages (3900 chars per chunk).

Completion Event Truncation

The completion event injected back into the parent conversation is a bounded copy of the subagent's streamed transcript. When the cap drops content, the event carries a short preview + the transcript's file path (not a bare truncated blob), and the parent reads the rest on demand — the read tool (offset/limit), grep, or the spawn_status MCP tool — instead of re-running the subagent.

The full transcript lives at ~/.kiro/crew/subagents/<id>/result.txt and is retained for a grace window after delivery (default 1 hour) so those reads succeed; the reaper then prunes it.

Three agent.* config knobs control what the parent session sees:

KeyValuesDefaultEffect
agent.completion_keep"head" / "tail" / "both""head"Which end of the transcript to keep when it exceeds the cap
agent.completion_keep_charsint (0 disables)3000Character cap applied after completion_keep
agent.subagent_result_ttl_secsint (seconds)3600How long the delivered result.txt is kept before the reaper prunes it. The window starts when the completion reaches the parent, so a completion queued behind a long turn does not spend it waiting

Pick the mode that matches how your agents emit their useful output:

  • head — first N characters. Best for agents whose verdict appears up front (verdict-then-evidence).
  • tail — last N characters. Best for agents that narrate throughout and summarize at the end (developer agents, code reviewers, on-call triage).
  • both — roughly N/2 from the head, a middle marker, and N/2 from the tail. Best for parent agents that need both the task framing and the conclusion.

Set completion_keep_chars: 0 to disable truncation entirely.

Set via kirocrew config set agent.completion_keep tail or by editing ~/.kiro/crew/config.json directly.

Reading the full transcript on demand

spawn_status reads the retained transcript by agent ID and supports line-oriented paging (like reading code) for large results:

  • spawn_status(agent_id, limit=200) — first 200 lines
  • spawn_status(agent_id, offset=200, limit=200) — next page
  • spawn_status(agent_id, grep="ERROR|FAIL") — only lines matching the regex

A paged/filtered response is prefixed with a continuation header (showing lines X-Y of N | more available — call again with offset=Y). With no paging args it returns the full transcript. You can also point the generic read / grep tools straight at the result_path from the completion event.