Skip to main content

Rate-limit vitals for Claude Code — burn rate, cache health, and baseline shift detection.

Project description

claude-code-vitals

Know your limits before they know you.

demo

A passive, always-on rate limit monitor for Claude Code. Tracks drift, predicts depletion, detects cache resets, and tells you when to switch models. Zero token cost. Zero external dependencies.

Opus 4.6 (1M context)  |  5h: 87% left  |  7d: 84% left  |  resets 2h 17m

Percentages are color-coded: green (<50% used), yellow (50-80%), red (>80%).

The Problem

You're deep in a coding session. Claude starts responding slower, or cuts off early, or just stops working. You have no idea if:

  • You used too much quota today
  • Your rate limit ceiling shifted without warning
  • There's a temporary throttle during a model transition
  • Your cache just reset and you're burning 5x more budget

Existing tools show current usage. Nobody tracks whether the ceiling itself changed, predicts when you'll run out, or watches your prompt cache health.

Install

pipx install claude-code-vitals
ccvitals init
# Restart Claude Code — done.

Or with pip:

pip install claude-code-vitals
ccvitals init

That's it. ccvitals init configures your Claude Code status bar automatically.

What You See

Normal — clean single row

Status bar: Opus 4.6, 5h and 7d usage, reset countdown

Usage spike — drift detected, with attribution

Status bar showing USAGE SPIKE +19.5% (baseline shift)

Running low — depletion ETA, compact warning, switch hint

Status bar showing runs out 17m, compact warning, try Sonnet

A week with ccvitals in 30 seconds

first signal

Simulated readings, real pipeline: the 5h window sawtooths all week with zero false alarms; a sustained ceiling shift is confirmed after three consecutive readings.

Multi-Row Progressive Disclosure

Row 1 always shows essentials (model, percentages, countdown). Row 2 appears only when something needs attention (alerts, cache issues, depletion warnings). Clean when everything is fine.

How It Works

flowchart TD
    A["Anthropic API servers"] -->|"HTTP headers: anthropic-ratelimit-unified-*"| B["Claude Code (parses headers internally)"]
    B -->|"stdin JSON with rate_limits, cost, model, context_window"| C["ccvitals run"]
    C --> D["Log to ~/.claude-code-vitals/history.jsonl"]
    C --> E["Compare to rolling median baseline"]
    C --> F["Compute per-prompt delta"]
    C --> G["Track context + cache state"]
    
    D --> H["Build burn rate profile\n(how fast utilization % increases per hour)"]
    H --> I{"Same burn rate,\nbut hitting limits sooner?"}
    I -->|"Yes"| J["USAGE SPIKE\n(baseline shift)"]
    I -->|"No — burn rate increased"| K["USAGE SPIKE\n(you're using more)"]
    
    E --> L{"Current vs. median:\ndeviation > threshold?"}
    L -->|"Yes, 3+ consecutive"| M["Signal: USAGE SPIKE or USAGE DROP"]
    L -->|"No"| N["STABLE (hidden — clean status bar)"]
    
    F --> O["Per-prompt delta display\n+1.2% last prompt"]
    
    G --> S{"Cache hit rate\ndropping?"}
    S -->|"Yes"| T["Cache miss warning\n+ root cause detection"]
    S -->|"No"| U["Cache healthy — hidden\n(shown only when <80%)"]
    
    G --> V{"Context near\ncompact threshold?"}
    V -->|"Yes"| W["Compact warning\n(per-model thresholds)"]

The key insight

Every interaction with Claude Code generates a reading. Over time, claude-code-vitals builds your burn rate -- how fast your utilization increases per hour of usage.

  • Same burn rate + hitting limits sooner -- the ceiling shifted. You're using the same amount but getting less headroom.
  • Higher burn rate + hitting limits at the same time -- your consumption increased. The ceiling is unchanged.

This is how claude-code-vitals separates a ceiling shift from a behavior change -- with math, not guesswork.

Features

Rate Limit Intelligence

  • Drift detection -- rolling median baseline comparison with attribution ("you're using more" vs. "baseline shift")
  • Four signals -- USAGE SPIKE (yellow), USAGE DROP (blue), COLLECTING (building baseline), STABLE (hidden)
  • Per-model burn-rate tracking -- the 5h/7d windows are shared across all models; each model's burn rate against that shared window is tracked separately (Opus drains it ~3-5x faster than Sonnet)
  • Burn rate + depletion prediction -- "runs out 45m" based on your current consumption rate (red <60min, yellow <5hr)
  • Model switch suggestions -- "try Sonnet (slower burn)" when you're on Opus and the shared window is >70% used
  • Reset countdown -- time until your 5-hour window resets

Per-Prompt Delta

  • +2.3% last prompt shown after every response

Context + Cache Intelligence

  • Context tracking -- "ctx: 48% (96k)" with color-coded percentage
  • Cache hit rate -- shown only when degraded (<80%); hidden when healthy to keep the bar clean
  • Cache miss detection -- identifies root cause when cache drops
  • Compact warnings -- alerts before auto-compaction resets your cache chain
  • Idle gap warnings -- notifies when 5-minute cache TTL is at risk

All cache/context elements use progressive disclosure -- they only appear when something needs your attention.

Display

  • Color-coded urgency -- green (<50% used), yellow (50-80%), red (>80%)
  • Cost display -- "$3.50" session cost (toggleable)

Passive by Design

  • Zero API calls -- reads data Claude Code already provides
  • Zero token cost -- purely passive observation
  • Zero external dependencies -- pure Python standard library, runs in well under 100ms

Progressive Disclosure

The status bar shows only what matters right now. When everything is fine, you see 4 elements. Alerts, cache warnings, and switch hints only appear when they need your attention. For the full picture anytime: ! ccvitals status --all-models.

Commands

ccvitals init                           # One-time setup
ccvitals status                         # Show current drift analysis
ccvitals status --all-models            # Show all models at once
ccvitals status --show-readings         # Include readings count
ccvitals status --show-remaining        # Show remaining % instead of used %
ccvitals budget                         # How long the shared window lasts per model
ccvitals suggest                        # Models ranked by burn rate
ccvitals baseline                       # Show/maintain rolling baselines (reset|freeze|window)
ccvitals explain                        # Full status bar guide
ccvitals explain cache                  # Prompt cache mechanics
ccvitals explain compact                # Auto-compaction + cache chain breaks
ccvitals explain models                 # Model differences + shared window
ccvitals config list                    # View all settings
ccvitals config set <key> <value>       # Change any setting
ccvitals privacy                        # View privacy policy
ccvitals uninstall                      # Remove configuration
ccvitals --version                      # Show version
ccvitals suggest: shared 5h window, models ranked by burn rate ccvitals budget: how long the shared window lasts at each model's burn rate

Configuration

View and change settings from the CLI -- no file editing needed:

ccvitals config set show_remaining true    # Show remaining % instead of used
ccvitals config set show_readings true     # Show readings count in status bar
ccvitals config set show_cost true         # Show session cost ($) in status bar
ccvitals config set show_pattern true      # Show time-of-day patterns
ccvitals config set all_models true        # Always show all models in status
ccvitals config set compact true           # Single-line or expanded view
ccvitals config set show_source true       # Show data source in status bar
ccvitals config set threshold_pct 15       # Adjust drift sensitivity
ccvitals config set color false            # Disable ANSI color output
ccvitals config list                       # See all current settings

All settings live in ~/.claude-code-vitals/config.toml:

[tracking]
baseline_window_days = 7       # Rolling window (1-84 days)
threshold_pct = 10             # % deviation to trigger signal
debounce_count = 3             # Consecutive readings to confirm

[display]
compact = true                 # Single-line (true) or expanded (false)
show_pattern = true            # Show time-of-day patterns
show_remaining = false         # true = show 88% left, false = show 12% used
show_readings = false          # Show readings count in status bar
all_models = false             # Show all models in status command
show_cost = false              # Show session cost ($) in status bar
show_source = false            # Show data source in status bar
color = true                   # ANSI color output

Session Tracking

claude-code-vitals records your Claude Code session ID with each reading and uses it internally to keep burn-rate math honest — consumption deltas are only computed between readings from the same session, so a parallel session can't inflate your burn rate.

Known limitation: Session detection is best-effort. With multiple concurrent sessions, cross-session readings are excluded from burn-rate pairs, which can delay a burn-rate estimate until two same-session readings exist.

Architecture

Claude Code -> stdin JSON -> ccvitals
                              |-> logger.py    (append to history.jsonl)
                              |-> detector.py  (rolling median + drift + burn rate)
                              |-> renderer.py  (ANSI status bar + cache + delta)

Zero external dependencies. Pure Python standard library. Runs in well under 100ms.

Key Discoveries

Things we learned by watching the data that Anthropic doesn't document:

  • Shared window, per-model burn rate -- the 5h and 7d windows are shared across all models (and across Claude Code, chat, and Cowork); switching models does not reset them. But the heavy models (Opus, Fable) burn the shared window fastest and each have their own tighter cap, so switching to a lighter model extends how long the window lasts and lets you keep working past the Opus/Fable limit.
  • Opus costs 3-5x more -- Opus consumes roughly 3-5x more rate limit budget per request than Sonnet.
  • 5-minute cache TTL -- prompt cache entries expire after 5 minutes of inactivity. Taking a break costs money on your next prompt.
  • Auto-compact resets cache -- when Claude Code auto-compacts your context, the entire cache chain resets. The first prompt after compaction is expensive.

See ccvitals explain cache and ccvitals explain models for details.

FAQ: Where did my usage go?

Claude Code shows a single percentage, so a ceiling change and a behavior change look identical. When your limit seems to vanish, it's usually one of six things -- and ccvitals is built to tell them apart:

  1. One shared pool. The 5h and 7d windows are shared across every model (and across Claude Code, chat, and Cowork). There's no separate per-model balance. → ccvitals suggest, ccvitals budget
  2. Heavy models burn faster. Opus and Fable drain the shared window several times faster per request than Sonnet/Haiku -- Fable is the heaviest. → ccvitals suggest ranks models by burn rate
  3. Cache invalidation. A 5-minute idle gap or an auto-compact resets your prompt cache; the next prompt is expensive. → ccvitals explain cache, ccvitals explain compact
  4. Context growth. A larger context costs more per prompt. → the ctx: indicator in the status bar
  5. The ceiling itself moved. Your limit can change (plan changes, promotions). ccvitals flags this as a baseline shift -- same burn rate, but hitting the wall sooner. → the drift signal in the status bar

Model eligibility and limits vary by plan and change over time -- ccvitals reports only what it can observe (your utilization and burn rate), never your plan tier. For current limits, Fable access, and any promotions, see Anthropic's pricing.

Data Stored

Each observation in ~/.claude-code-vitals/history.jsonl:

{
  "ts": "2026-03-30T14:22:00Z",
  "provider": "anthropic",
  "model_id": "claude-opus-4-6",
  "model_name": "Opus 4.6",
  "session_5h_pct": 42.0,
  "weekly_7d_pct": 67.0,
  "source": "statusline"
}

Privacy

Everything stays local. Nothing is sent anywhere. No analytics, no telemetry, no phone-home.

Future versions may add opt-in anonymous crowdsourcing (utilization percentages only -- never prompts, keys, or identity). See ccvitals privacy for details.

Roadmap

  • Phase 1: Local monitoring + drift detection with attribution
  • Per-model burn-rate tracking (Opus, Sonnet, Haiku burn rates tracked separately)
  • Reset countdown + color-coded thresholds
  • CLI config management (config set/list)
  • Session cost display
  • Self-documenting (ccvitals explain with subtopics)
  • Burn rate + depletion prediction
  • Per-prompt delta
  • Model switch suggestions
  • Phase 2: Context + cache intelligence
  • Cache hit rate monitoring with per-model thresholds
  • Compact warnings + idle gap detection
  • suggest and budget commands
  • Multi-provider support (OpenAI, Google)
  • Crowdsourced baseline (solve cold-start problem)
  • Public dashboard

Why This Exists

15+ GitHub issues on the Claude Code repo requesting rate limit visibility in the statusline. Multiple community workarounds built. Users reverse-engineering undocumented OAuth endpoints. The demand is overwhelming.

claude-code-vitals goes further: it doesn't just show you where you are now. It tracks changes over time, predicts when you'll run out, watches your cache health, and flags when something shifted -- the only tool that does all of this.

License

MIT

Author

Jatin Mayekar

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

claude_code_vitals-0.4.0.tar.gz (63.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

claude_code_vitals-0.4.0-py3-none-any.whl (46.3 kB view details)

Uploaded Python 3

File details

Details for the file claude_code_vitals-0.4.0.tar.gz.

File metadata

  • Download URL: claude_code_vitals-0.4.0.tar.gz
  • Upload date:
  • Size: 63.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.7

File hashes

Hashes for claude_code_vitals-0.4.0.tar.gz
Algorithm Hash digest
SHA256 3c3a838eac04b308060ccc2d538dea8b6a4b1e6a6c98b56c616aafb603fa7578
MD5 4586c31790c988cb161cfa3493e8f95b
BLAKE2b-256 d96c1266772461beb234707897bc42754a497eafdce93805e3596e943bbcdcf9

See more details on using hashes here.

File details

Details for the file claude_code_vitals-0.4.0-py3-none-any.whl.

File metadata

File hashes

Hashes for claude_code_vitals-0.4.0-py3-none-any.whl
Algorithm Hash digest
SHA256 1b553f66f2afd753ba826e573bd41e9ccf689902e4cbd9ea0beba5d4dff69f61
MD5 668cfbcc3987193365f64f9ca21b9391
BLAKE2b-256 402f9ad6fe65525c47ca1fd5611ea21087ade98141789dcfd6a79daa04926818

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page