overnight-agent headless-mode claude-cli rate-limiting api-quota

Claude Code Shared API Quota: Headless Agent vs Interactive Session

Claude Code Shared API Quota: Headless Agent vs Interactive Session

Problem

The overnight agent (claude -p in tmux) and an interactive Claude Code session (claude --dangerously-skip-permissions) share the same API rate limit when running on the same machine under the same user account. The agent cannot run while you are actively chatting.

Symptom

The agent hits the rate limit and logs:

You've hit your limit · resets 1am (America/Vancouver)

Meanwhile, the user is actively using Claude Code in another terminal. The rate limit reset time passes, but the agent still can’t start because the interactive session keeps consuming quota.

The cron restart script dutifully retries every 20 minutes, each attempt failing immediately with the rate limit error.

Root Cause

Claude Code CLI sessions authenticate with the same account credentials regardless of how they’re launched. All sessions — interactive, headless (-p), resumed (--continue) — draw from the same API rate limit pool.

This means:

  • Running claude -p in tmux + claude interactively = shared quota
  • The overnight agent is effectively paused whenever you’re chatting
  • The cron restart script wastes restart attempts on rate limit failures

Solution

Option 1: Don’t chat while the agent runs (simplest)

Close your interactive session before launching the overnight agent. The agent gets the full quota. This is the intended use case — agent runs while you sleep.

Option 2: Dedicated computer with separate account

The original overnight agent plan calls for a dedicated second computer with its own overnight user account and separate Claude Code authentication. This gives the agent its own rate limit pool.

Option 3: Separate API key (programmatic)

Set ANTHROPIC_API_KEY in the run.sh environment to use a different API key with its own quota:

# In run.sh or resume.sh
export ANTHROPIC_API_KEY="sk-ant-..."
claude -p "..." --dangerously-skip-permissions ...

This requires a separate Anthropic API account/key.

Impact on Dashboard

The dashboard was updated to distinguish between states:

StateHeartbeatMeaning
runningGreen pulseClaude process alive and working
stalledRed pulsetmux alive but claude exited (rate limit, crash)
deadGrey pulsetmux session gone, waiting for cron
completedBlue solidDONE file exists
failedRed solidFAILED file exists

The stalled state was added specifically because the rate limit causes claude to exit while tmux stays alive (due to exec bash fallback in run.sh).

Prevention

  • Launch overnight agents after closing interactive sessions
  • Use a dedicated machine or API key for autonomous agents
  • The rate-limited circuit breaker (max 3 restarts/hour) prevents wasting all restart attempts during shared-quota situations — the agent will resume once quota frees up