Show your Claude usage limits in the terminal while you work. Two complementary
tools, no third-party dependencies (just python3), no network and no
credentials by default:
claude-monitor.py— a full-screen, live dashboard (CLAUDE TOKEN MONITOR style) you run in its own terminal pane.claude-limits.py— a one-line Claude Code status line that sits at the bottom of your Claude session.
They cooperate: the status line is the only place Claude Code exposes the real 5h / 7d limit percentages (it gets them on stdin), so it caches them to a file that the monitor reads back. Result — the monitor shows real numbers with zero network calls.
✦ ✧ ✦ CLAUDE TOKEN MONITOR ✦ ✧ ✦
════════════════════════════════════
📊 Token Usage: 🟢 [███░░░░░░░░░░░░░░░░░░░░░] 8.0%
⏳ Time to Reset: ⏰ [███████████████████░░░░] 40m
🎯 Tokens: 1,365,721 / ~17,071,512 (15,705,791 left)
🔥 Burn Rate: 46708.4 tokens/min
💰 Cost: $11.16 this window at API rates (~$28.58/h)
🏁 Predicted End: 21:15
🔄 Token Reset: 16:20
📅 Weekly (7d): [░░░░░░░░░░░░░░░░░░░░░░░░] 1.0% resets in 6d 13h
⏰ 15:38:39 📝 Smooth sailing... | Ctrl+C to exit
source: status-line cache
Clone the repo wherever you like (the examples below use ~/claude-limits —
adjust the path if you cloned elsewhere):
git clone https://github.com/ChekeEdd/claude-limits.git ~/claude-limitsThen, in a separate terminal (next to your Claude Code window):
python3 ~/claude-limits/claude-monitor.pyIt redraws every second until you press Ctrl+C. A handy shell alias:
echo "alias climits='python3 ~/claude-limits/claude-monitor.py'" >> ~/.zshrc| Field | Source | Meaning |
|---|---|---|
| Token Usage % | real (cache/--live), else estimate |
how much of the 5‑hour limit is used |
| Time to Reset | real reset time, else block+5h | bar fills as the window approaches reset |
| Tokens used / limit | transcripts (effective*) + real % | ~ means the limit is an estimate |
| Burn Rate | transcripts | effective tokens/min over the last 30 min |
| Cost | transcripts × API tariffs | what this 5h window's usage would cost at list prices, with the per‑model rate of every message (subscription users don't pay this — it's a value gauge) |
| Predicted End | real 5h % velocity (else burn) | when 5h hits 100%; shows safe ✓ if you reset first, plus a 1.3× pace tag |
| Token Reset | real, else estimate | clock time the 5‑hour window resets |
| Weekly (7d) | real (cache/--live) |
weekly limit %, shown only when real data exists |
* Effective tokens = input + output + cache‑writes + 0.1 × cache‑reads (cached context is re‑sent every turn and billed ~0.1×, so it's weighted down — otherwise a big‑context session shows an absurd burn rate). Streamed duplicates in the transcripts (the same message logged several times) are deduplicated by message id + request id. The % bar comes from the real limit numbers when available, not from this count.
The Cost line is the money‑accurate view: per‑model input/output rates (e.g. Fable 5 $10/$50 per 1M, Opus 4.8 $5/$25, Sonnet 4.6 $3/$15, Haiku 4.5 $1/$5), cache writes at 1.25× input, cache reads at 0.1×. Effective tokens deliberately do NOT track money — output costs 5× input at every tier — they approximate rate‑limit weight; use 💰 for dollars.
--live→ querieshttps://api.anthropic.com/api/oauth/usageusing your OAuth token from the macOS Keychain. Real 5h/7d %, even with no session open. (macOS may ask once to allow Keychain access — it's your own token.)- status-line cache → real 5h/7d % written by
claude-limits.pywhenever a Claude session is running (default, no network). - transcripts only → if neither is available, tokens/burn/prediction still work;
the % is estimated against your largest past 5‑hour block. If there's no past
block to compare against, it honestly shows
—%and asks you to open a session or pass--limit.
--interval SECONDS refresh rate (default 1)
--live also hit the OAuth usage API for real numbers
--limit TOKENS set the token limit instead of auto-detecting
--once render a single frame and exit
--ascii ASCII-only bars (no unicode blocks)
--no-color disable color
This puts the limits in the same terminal you're working in — the Claude Code status bar at the bottom. Two looks:
dashboard (multi-line mini-monitor — what the install below wires up; the
script's own default is full):
╭──────────────────────────────────────────────────────────────╮
│ ✦ Opus 4.8 · ctx 34% · 💰 $4.10 │
│ 📊 5h [██████████░░░░░░░░░░░░░░░░░░] 28.0% ⟳ 2h00m │
│ 📅 7d [████░░░░░░░░░░░░░░░░░░░░░░░░] 12.0% ⟳ 4d15h │
│ 🏁 limit ~17:24 (1h30m) · 🔥 burn 30m [█████████████] 2.7k/m 1.3× pace │
╰──────────────────────────────────────────────────────────────╯
A rainbow frame wraps the dashboard by default — a smooth 24-bit gradient
running once around the border (seamless in Ghostty's truecolor) — and the colors
flow around the frame over time. The motion advances once per status-line
refresh, so set "refreshInterval": 1 (below) for a ~1 fps flow when idle. Turn
the frame off with CLAUDE_LIMITS_BORDER=off, draw an uncolored box with
CLAUDE_LIMITS_BORDER=plain, freeze the colors with CLAUDE_LIMITS_BORDER_ANIM=0,
or change the pace with CLAUDE_LIMITS_BORDER_SPEED=12 (faster, more motion per
tick) / 48 (slower, smoother).
- 🏁 Predicted End — when the 5‑hour window hits 100%, projected from the real
rate at which the % is climbing. Shows
5h safe ✓ resets firstwhen you'll reset before running out, or5h … gathering paceuntil it has enough samples. - 🔥 burn 30m — pace vs. what's sustainable until reset.
1.3× pace(red) = burning faster than you can afford this window;0.2×(green) = comfortable. The number is effective tokens/min from the current session. Both are trailing averages (burn: last 30 min, pace: last 20 min of the real %), not live flow — after you stop, they decay gradually as old activity ages out of the window (so a big number right after a heavy session doesn't mean something is still consuming tokens). - ⚠ ctx 88% → /compact — the
ctxsegment turns red and a macOS popup fires when the context window fills up (see Context-full popup below).
full (compact one-liner):
Opus 4.8 │ 5h ██░░░░░░░░ 24% 2h11m │ 7d ████░░░░░░ 41% 3d4h │ ctx 8%
🟢 <50% · 🟡 50–79% · 🔴 80–94% · 🔴bold ≥95%. Both styles read the rate_limits
block Claude Code (v2.1.80+) hands them on stdin (so the % and resets are real)
and write the real numbers to ~/.claude/claude-limits-cache.json so the
standalone monitor can reuse them. The dashboard style additionally parses the
current session transcript for the burn rate and auto-sizes its bars to the terminal
via COLUMNS (Claude Code v2.1.153+); the full one-liner uses a fixed
CLAUDE_LIMITS_BAR_WIDTH.
Add to ~/.claude/settings.json (point the path at your clone):
{
"statusLine": {
"type": "command",
"command": "CLAUDE_LIMITS_STYLE=dashboard python3 ~/claude-limits/claude-limits.py",
"refreshInterval": 1,
"padding": 0
}
}refreshInterval: 1 (the documented minimum, in seconds) re-runs it every second
so the reset countdown ticks and the rainbow frame flows while you're idle.
Bump it to 5 if you'd rather it run less often (the colors then shift in steps
instead of flowing). Restart Claude Code / start a new session to see it. Want the
slim one-liner instead? Drop CLAUDE_LIMITS_STYLE=dashboard from the command.
rate_limitsappears only for Claude.ai Pro/Max subscribers, and only after the first API response in a session — until then you'll seelimits: warming up…. On an API‑key account the block isn't sent.
| Variable | Default | Meaning |
|---|---|---|
CLAUDE_LIMITS_STYLE |
full |
dashboard (multi-line) · full · compact · minimal |
CLAUDE_LIMITS_SHOW |
model,5h,7d,ctx |
(single-line styles) segments & order: model,5h,7d,ctx,cost |
CLAUDE_LIMITS_BORDER |
rainbow |
dashboard frame: rainbow (24-bit gradient) · plain · off |
CLAUDE_LIMITS_BORDER_ANIM |
on | colors flow around the frame over time (0 to freeze; needs refreshInterval: 1) |
CLAUDE_LIMITS_BORDER_SPEED |
24 |
seconds for one full lap of the rainbow (longer = smoother, smaller per-tick step) |
CLAUDE_LIMITS_BAR_WIDTH |
10 |
bar length |
CLAUDE_LIMITS_CTX_WARN |
80 |
context % that triggers the red warning + popup |
CLAUDE_LIMITS_LIMIT_WARN |
90 |
5h/7d usage % that triggers the urgent near-limit popup |
CLAUDE_LIMITS_NOTIFY |
1 |
0 → disable all macOS popups |
CLAUDE_LIMITS_ASCII |
off | 1 → ASCII bars |
CLAUDE_LIMITS_NO_COLOR |
off | 1 → no color (honors NO_COLOR) |
The status line fires macOS notifications (debounced, via
~/.claude/claude-limits-notify.json) for two things:
- Context filling up — at
CLAUDE_LIMITS_CTX_WARN% (default 80): "Context NN% full — run /compact or /clear" (sound: Submarine). Thectxsegment also turns red. - Near the usage limit — when the 5h or weekly window crosses
CLAUDE_LIMITS_LIMIT_WARN% (default 90): "5‑hour limit NN% used — resets in …, wrap up or switch model" (louder sound: Sosumi).
Each alarm warns once when it crosses, again if it climbs further (+7 ctx / +4 limit),
or after a 10‑min cooldown if it has kept growing, and re-arms once the value stays
below the threshold for a minute. Limit data whose resets_at is already in the past
is treated as expired (an idle session keeps reporting the previous window after a
reset): the status line renders that window as 0% until the next API response
brings fresh numbers, popups ignore it, and a hard 2‑min floor between popups per
alarm stops any flapping value from storming — so the moment the 5h window flips over
can't spam notifications or freeze the bar at the old %. The first time one fires,
macOS may ask to allow notifications for your terminal app (Ghostty) — allow it.
Turn all popups off with CLAUDE_LIMITS_NOTIFY=0. Tune thresholds, e.g.
CLAUDE_LIMITS_CTX_WARN=70 CLAUDE_LIMITS_LIMIT_WARN=85.
The predicted-end / burn-bar line builds a tiny rolling history of the real 5h % in the cache file, so it needs a minute or two of activity before it shows a pace. Works great in Ghostty (truecolor + clean multi-line rendering).
A Claude Code plugin (skills/agents/hooks/MCP) cannot register a status line or
a background TUI — those live in settings.json and as a standalone script. So this
ships as two small scripts + a one‑line settings entry, which is the supported way to
get limits into your terminal.
- Status line: remove the
statusLineblock from~/.claude/settings.json. - Monitor: just stop running it (and drop the alias). Optionally delete
~/.claude/claude-limits-cache.json.