Skip to content

perf: persistent claude process via --input-format stream-json #7

Description

@helloiamvu

Each request currently spawns a fresh claude -p process (~5-7s startup overhead).

claude -p supports --input-format stream-json which accepts stdin messages in NDJSON format:

{"type":"user","message":{"role":"user","content":"say pong"},"session_id":"<uuid>"}

This enables keeping a persistent claude process warm and feeding messages via stdin — eliminating the cold start entirely. Responses would start in <1s instead of 5-7s.

Approach:

  1. On proxy startup, spawn a persistent claude -p --input-format stream-json --output-format stream-json --verbose --permission-mode bypassPermissions
  2. Multiplex: track which request each result event belongs to via session_id/uuid correlation
  3. Feed incoming API requests as stdin messages
  4. Route output events back to the correct HTTP response
  5. Auto-restart the process if it dies

Research done:

  • Input format: {"type":"user","message":{"role":"user","content":"text"},"session_id":"UUID"}
  • Output includes session_id for correlation
  • Process stays alive between messages
  • Supports multi-turn conversation natively

Complexity: Medium-high (requires careful multiplexing and error handling)
Priority: High — this is the biggest UX improvement possible

Refs: https://code.claude.com/docs/en/headless

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions