`claude -p` provides no feedback during long requests — forces blind timeouts, wastes quota

Resolved 💬 4 comments Opened Mar 8, 2026 by snailuj Closed Apr 6, 2026

Summary

claude -p gives no signal that the server is still processing a request. For batch workloads where response times vary unpredictably, the client has no way to distinguish "server is working, just slow" from "server is stuck." The only option is a blind timeout — which, when the server is transiently slow, pours tokens down the drain.

What happened

Running an overnight LLM enrichment batch for Metaforge (open source visual thesaurus), 53 out of 85 batches timed out at 300s — a 62% failure rate. This consumed roughly 16% of my weekly Max 5x quota with zero output delivered. The identical workload processed 8,000 items in ~4 hours two days earlier with no timeouts. The slowdown was transient and server-side.

Command pattern (called via Python subprocess):

claude -p \
  --output-format json \
  --model sonnet \
  --max-turns 1 \
  --no-session-persistence \
  --strict-mcp-config \
  --mcp-config empty_mcp.json \
  < prompt.txt

Log pattern (repeating for hours):

BATCH FAILED after retries: Command '['claude', '-p', '--output-format', 'json',
'--model', 'sonnet', '--max-turns', '1', ...]' timed out after 300 seconds

The problem

The client is flying blind. When claude -p is called:

  • There is no keep-alive, heartbeat, or progress signal
  • There is no way to tell if the server is 10% done or 99% done
  • There is no indication of whether the server is responding slowly or has silently failed
  • There is no per-request usage report, so you can't see what a timed-out call cost

This forces a lose-lose choice:

| Strategy | What happens when the server is transiently slow |
|----------|--------------------------------------------------|
| Short timeout (e.g. 300s) | Fail fast, but every timed-out request wastes its full quota — server did the work, client didn't receive it |
| Long timeout (e.g. 600s) | Wait longer per call, and if the slowdown persists, waste even more quota per failure while the batch crawls |
| No timeout | Risk the batch hanging indefinitely on a stuck request |

With no feedback from the server, there is no informed choice — only guessing. It's like paying for metered water with no meter, no sound from the pipes, and no way to tell if the tap is running or the main has burst. You set a timeout because you have no other option.

Suggested improvements

1. Keep-alive / heartbeat for long-running claude -p calls

Some periodic signal to stderr (or a status stream) indicating the server is still processing. Even a simple heartbeat every 30s would let batch clients distinguish "slow but progressing" from "stuck" and set timeouts accordingly. This is the single most impactful change for programmatic claude -p usage.

2. Per-request usage reporting in claude -p output

When a claude -p call completes, include the token cost in the response — e.g. a usage field in JSON output mode:

{"result": "...", "usage": {"input_tokens": 1523, "output_tokens": 3841}}

This would let batch users detect anomalies and waste early (per-call, not the morning after), and make informed decisions about batch size, retry strategy, and timeout thresholds.

3. Publish subscription usage accounting

The costs documentation states that /cost "isn't relevant for billing purposes" for subscribers and directs them to /stats, which shows usage patterns but not accounting. The usage limits page describes a "conversation budget" without explaining how it's calculated.

Users can't optimise what they can't measure. Is subscription usage based on input tokens? Output tokens? Both? Weighted by model? A time-based "active hours" metric? Without knowing the formula, it's impossible to reason about whether a workload is cost-effective, predict when you'll hit limits, or detect waste.

Environment

  • Claude Code version: 2.1.63
  • Plan: Max 5x ($100/month)
  • OS: Linux (WSL2)
  • Model: Sonnet (via --model sonnet)

Context

Metaforge is an open source visual thesaurus and metaphor engine. The data pipeline uses claude -p to extract semantic properties from WordNet synsets — thousands of structured extraction calls run as overnight batches. The API isn't viable for an unfunded open source project at this volume, so the CLI + Max plan is the only practical path.

The transient nature of the timeouts (fine one day, 62% failure rate the next) suggests server-side load variance. That variance is outside the user's control — but the tools to respond to it intelligently (heartbeat, per-call usage, clear accounting) don't exist yet. The result is predictable: wasted quota and frustrated users.

View original on GitHub ↗

This issue has 4 comments on GitHub. Read the full discussion on GitHub ↗