Feature Request: Server/IPC hook type for persistent hook processes
Problem
Hooks currently use type: "command" which spawns a new Node.js process per hook invocation. For plugins with many hooks (e.g., 63 entries), this means 7+ process spawns per tool call, each incurring ~50-80ms of V8 cold-start overhead. On a typical Bash call:
- PermissionRequest: 2 spawns × ~75ms = ~150ms
- PreToolUse: 3-5 spawns × ~75ms = ~225-375ms
- PostToolUse: 3 spawns × ~75ms = ~225ms (partially async)
- Total blocking overhead: ~375-525ms per tool call
The async: true flag (CC 2.1.45) helps for non-blocking hooks, but blocking hooks (permission, pre-tool validation) cannot be made async.
Proposed Solution
Add a type: "server" hook type that connects to a persistent process via Unix domain socket (or named pipe on Windows):
{
"hooks": {
"PreToolUse": [{
"type": "server",
"socket": "/tmp/my-plugin-{sessionId}.sock",
"matcher": "Bash"
}],
"PermissionRequest": [{
"type": "server",
"socket": "/tmp/my-plugin-{sessionId}.sock",
"matcher": "Bash"
}]
}
}
How it works
- Plugin starts a daemon at
SessionStart(via existingtype: "command"hook) - Daemon listens on Unix socket, keeps all hook logic warm in memory
- CC sends hook events as JSON over IPC instead of spawning processes
- Daemon returns hook result over IPC
- Daemon shuts down at
Stopevent
Expected performance
- Per-call overhead: ~2-5ms (IPC round-trip) vs ~75ms (process spawn)
- 94-99% reduction in hook latency
- Zero V8 cold-starts after initial daemon startup
- Single process instead of 7+ per tool call
Workaround
We're currently using a "hook proxy" pattern where spawned processes connect to a self-managed daemon via Unix socket. This works but adds ~15ms overhead per call (Node start + socket connect). Native CC support would eliminate this entirely.
Context
OrchestKit plugin (62 skills, 37 agents, 63 global hooks). The hook system is the primary performance bottleneck — LLM calls take seconds but hook overhead adds 500ms+ of unnecessary latency to every tool call.
This issue has 5 comments on GitHub. Read the full discussion on GitHub ↗