Cap Parallel Subagent Concurrency

SubagentStart has no blocking support, so this can't actually deny the spawn — but it logs active-count and surfaces a visible warning the moment concurrency crosses a configured ceiling, which is still enough to catch a runaway fan-out before it becomes an expensive surprise.

Cost & Usage Controls Event: SubagentStart Claude Code Open source · Free

1. Save this as the hook script

#!/usr/bin/env python3
"""SubagentStart hook — warns once active subagent count exceeds a
ceiling. Tracks active_id set in a state file; a companion SubagentStop
hook should remove the id when it finishes."""
import json, sys
from pathlib import Path

data = json.load(sys.stdin)
CONCURRENCY_CEILING = 5
state_path = Path(data.get("cwd", ".")) / ".claude" / "active_subagents.txt"

active = set(state_path.read_text().splitlines()) if state_path.exists() else set()
active.add(data.get("agent_id", ""))
state_path.parent.mkdir(parents=True, exist_ok=True)
state_path.write_text("\n".join(active))

if len(active) > CONCURRENCY_CEILING:
    print(f"WARNING: {len(active)} subagents active at once, above the "
          f"{CONCURRENCY_CEILING} concurrency ceiling.", file=sys.stderr)
    sys.exit(1)

sys.exit(0)

Save to a path inside your project, e.g. .claude/hooks/cap-parallel-subagent-concurrency.sh, then chmod +x it.

2. Wire it into .claude/settings.json

{
  "hooks": {
    "SubagentStart": [
      {
        "hooks": [
          {"type": "command", "command": "python3 .claude/hooks/cap-parallel-subagent-concurrency.py"}
        ]
      }
    ]
  }
}

Before you use this

A hook runs with your local shell's permissions — review the script above before adding it, the same way you'd review any script you didn't write yourself. See our guide on hook security risks for the specific CVEs this category of feature has already produced.

Related hooks

← All hooks
FEEDBACK