Claude Code status line: show context, cost and usage limits
The status line is a row at the bottom of Claude Code that runs a script of yours: Claude Code sends the script the session’s data as JSON and shows whatever it prints. The quickest way to get one is to type /statusline followed by what you want to see, and Claude Code writes the script for you. It isn’t decoration: it’s the one place that can show, all the time, the model, how full the context is, the session’s cost, your git branch, and on Pro and Max your 5-hour and weekly usage limits. It runs on your machine and uses no tokens.
- The one-line setup
- Set it up by hand
- What your script receives
- A script for context and limits
- When it updates
- Ready-made status lines
- VS Code, Claude Desktop and SSH
- When it stays blank
- Questions
The one-line setup
Describe what you want after the command, and Claude Code writes a script into ~/.claude/ and adds it to your settings:
/statusline show model name and context percentage with a progress bar
Run /statusline with nothing after it to copy your shell prompt instead. To remove the status line, run /statusline and ask it to clear it, or delete the statusLine entry from your settings.
Set it up by hand
Add a statusLine object to your user settings, or to a project’s settings for that project only:
~/.claude/settings.json
{
"statusLine": {
"type": "command",
"command": "~/.claude/statusline.sh",
"padding": 0
}
}
commandis a script path or an inline shell command. It runs in a shell, so a one-liner such asjq -r '"[\(.model.display_name)] \(.context_window.used_percentage // 0)% context"'works too.paddingadds spaces around the text; the default is 0.refreshInterval(version 2.1.97 and later) also re-runs the command every N seconds, at least 1. Use it for a clock, or for anything that changes while the session is idle.hideVimModeIndicatorhides the built-in-- INSERT --when your script shows the vim mode itself.
Claude Code picks the change up as soon as you save the file; no restart needed.
What your script receives
The script gets one JSON object on standard input each time it runs. The fields most people use (full list):
| Field | What it holds |
|---|---|
model.display_name | The current model’s name |
workspace.current_dir | The working folder; workspace.git_worktree names a linked worktree |
context_window.used_percentage | How full the context is, from 0 to 100; remaining_percentage is the rest |
context_window.context_window_size | 200,000 tokens by default, 1,000,000 on models with extended context |
rate_limits.five_hour.used_percentage | How much of the 5-hour limit you’ve used, with resets_at in Unix seconds |
rate_limits.seven_day.used_percentage | The same for the weekly limit |
cost.total_cost_usd | An estimate of the session’s cost at API list prices |
cost.total_duration_ms | How long the session has run |
cost.total_lines_added, total_lines_removed | Lines changed in the session |
session_name | The name from /rename, or the generated title |
effort.level | The reasoning effort, when the model supports it |
pr.number, pr.url | The open pull request for the branch, if any |
Three things to know:
- Limits only on Pro and Max.
rate_limitsappears for claude.ai Pro and Max subscribers, after the first response in a session, and each window can be missing. The docs don’t list it for Team, Enterprise or API keys. Read it with// emptyso the script doesn’t break without it. - The cost isn’t your bill. On a subscription,
total_cost_usdis what the session would cost on the API, worked out on your machine. It resets to $0 after/clear. - Context counts input only.
used_percentageis input tokens from the last response, so it can benullearly on, and/contextmay show a bit more because it also estimates messages since. It’s measured against the full window, so it isn’t the point where auto-compact kicks in if you changed that. When to compact covers what to do as it fills.
A script for context and limits
This one shows the model, the context, and your two usage limits with the time the 5-hour one resets. It needs jq, which macOS includes; on Linux install it from your package manager.
~/.claude/statusline.sh
#!/bin/bash
# Model, context, and the 5-hour and weekly limits with the 5-hour reset time
input=$(cat)
model=$(jq -r '.model.display_name' <<<"$input")
ctx=$(jq -r '.context_window.used_percentage // 0 | floor' <<<"$input")
five=$(jq -r '.rate_limits.five_hour.used_percentage // empty | floor' <<<"$input")
reset=$(jq -r '.rate_limits.five_hour.resets_at // empty | strflocaltime("%H:%M")' <<<"$input")
week=$(jq -r '.rate_limits.seven_day.used_percentage // empty | floor' <<<"$input")
line="$model | context ${ctx}%"
[ -n "$five" ] && line="$line | 5h ${five}% (resets $reset)"
[ -n "$week" ] && line="$line | week ${week}%"
echo "$line"
Make it executable with chmod +x ~/.claude/statusline.sh and point command at it. It prints something like Opus 5.5 | context 42% | 5h 63% (resets 15:00) | week 28%, and just the model and context until the limits arrive. To test it without Claude Code, pipe in sample JSON: echo '{"model":{"display_name":"Opus"}}' | ~/.claude/statusline.sh.
Each echo becomes its own row, so you can split it over two lines, and ANSI codes such as \033[33m color it in terminals that support them. For what the limits mean and how they reset, see Claude Code usage limits explained.
When it updates
The script runs when the session starts and again when a new response arrives, after /compact, when the permission or vim mode changes, when a limit window resets, and on each refreshInterval tick. Claude Code waits 300 ms for changes to settle and runs the script once, and a new update cancels a run that’s still going, so keep it fast: cache slow things such as git calls in a file named after session_id. While the session sits idle nothing triggers it, which is what refreshInterval is for.
Ready-made status lines
If you’d rather not write a script, the docs point to two community projects, and a third is popular for cost tracking. All three are third-party code that runs on every update, so read what you install:
- ccstatusline: a configurable status line with themes and widgets for context, session cost and session and weekly usage. Its setup screen runs with
npx -y ccstatusline@latest. - starship-claude: the status line through Starship, installed as a Claude Code plugin.
- ccusage statusline (marked beta): session and daily cost, burn rate, and what’s left of the current 5-hour block.
VS Code, Claude Desktop and SSH
- VS Code. The extension’s documentation doesn’t mention the status line, and users report that the graphical panel doesn’t show it. Run
claudein VS Code’s integrated terminal, or turn on the extension’suseTerminalsetting, to get it. - Claude Desktop has its own indicators instead: a Context card and a usage ring next to the model picker that shows your plan usage when clicked.
- Over SSH the script runs on the machine where Claude Code runs, so
jqandgithave to be installed there.
When it stays blank
- The script failed or printed nothing. The status line shows output only after the script exits with 0. Run
claude --debugto see its errors. - The folder isn’t trusted yet. The status line follows the same rule as hooks and stays blank until you accept the workspace trust dialog.
- It shows the wrong width.
tput colsdoesn’t work inside the script; read theCOLUMNSvariable instead. - On Windows commands run through Git Bash when it’s installed, otherwise PowerShell. Use forward slashes in paths.
Where Meowdoro fits
We built Meowdoro, a focus timer around the MacBook notch, and on purpose it leaves your status line alone. The status line shows the session you’re in; Meowdoro shows every Claude Code and Codex session at once, each with a ring for how full its context is, and suggests /compact at your break for the one that’s filling up (how it shows agents). The two work well together if you run several sessions. Try it and tell us what’s missing.
Questions
How do I show context usage in the Claude Code status line?
Print context_window.used_percentage from the JSON your script receives, or run /statusline show context percentage with a progress bar and let Claude Code write the script.
Can the status line show my usage limits?
Yes, on Pro and Max: rate_limits.five_hour and rate_limits.seven_day give the share used and the reset time, from version 2.1.80. They appear after the first response in a session.
Does the status line use tokens?
No. The script runs on your machine and doesn’t call the API.
Why is my status line blank?
Usually the script: it exited with an error or printed nothing. The other common cause is a folder whose trust dialog hasn’t been accepted yet. claude --debug shows the script’s errors.
Does the status line work in the VS Code extension?
Not in the graphical panel, by users’ reports; the docs don’t say either way. Run claude in the integrated terminal to get it.
How is this different from the status line in Codex?
Codex’s /statusline lets you pick from built-in items, including its rate limits, rather than running a script. See how to check your Codex usage.
Related guides
Sources: the Claude Code documentation on the status line, settings, commands, VS Code, Claude Desktop and the changelog; user reports in Claude Code’s issue tracker about VS Code and Desktop; the projects’ own pages. Read on October 30, 2026.