Claude Code status line: show usage, model and cost

The Claude Code status line runs your own script and shows its output at the bottom. It runs locally, uses no tokens, and /statusline writes one for you.

Contents

The Claude Code status line is a row at the bottom of the terminal that shows whatever your own script prints. Claude Code runs the script with the session's details as JSON (model, context use, cost, plan usage) and redraws the row as you work. Run /statusline to have one made for you, or write a short script and point your settings at it.

Everything here is from Anthropic's status line docs, read on 22 October 2026.

How the Claude Code status line works#

Three boxes left to right: Claude Code, your script, and the status line row. An arrow labelled JSON on stdin joins the first two, and one labelled stdout joins the last two. Claude Code model, context, cost Your script statusline.sh Status line at the bottom JSON on stdin stdout
  1. Claude Code runs the command you set in statusLine.
  2. It writes the session's data to the command's stdin as JSON.
  3. Whatever the command prints to stdout becomes the status line. Each line it prints is a row, and ANSI colours work.

It runs locally and doesn't use tokens. It sits above the built-in footer badges rather than replacing them, though with a custom status line Claude Code drops most of its keyboard hints, such as esc to interrupt.

When it redraws#

The script runs when a session starts or resumes, and again when:

  • a new reply from Claude arrives;
  • /compact finishes;
  • the permission mode or vim mode changes;
  • a 5-hour or weekly window in the data reaches its reset time;
  • a timer you set with refreshInterval elapses.

Updates are batched at 300 ms, and a run still going when the next one starts is cancelled. A script that calls curl or gh on every redraw can be cancelled before it prints, so cache anything slow in a file.

Set it up#

The quick way: /statusline#

Type /statusline and the row you want:

text
/statusline show model name and context percentage with a progress bar

Claude Code writes a script into ~/.claude/, asks you to approve the file edits, and adds the statusLine entry to your settings. With no description, /statusline copies the look of your shell prompt.

By hand#

Add a statusLine entry to ~/.claude/settings.json (every project) or a project's .claude/settings.json:

json
{
  "statusLine": {
    "type": "command",
    "command": "~/.claude/statusline.sh",
    "padding": 2
  }
}
  • type is always "command".
  • command is a script path or an inline shell command.
  • padding (optional) adds spaces of indent. Default 0.
  • refreshInterval (optional) re-runs the command every N seconds, minimum 1. Use it for a clock, or for git state that changes while Claude sits idle.

Claude Code reloads settings by itself and runs the script as soon as you save.

The fields worth showing#

The full schema is on Anthropic's page. These are the fields for usage, model and cost, plus a few that help when something looks wrong:

What you want to see Field Notes
Model model.display_name (or model.id) "Opus", "Sonnet"
Context used context_window.used_percentage Percent of the window, from the last reply. context_window.context_window_size says whether it's 200k or 1M
Session cost cost.total_cost_usd An estimate at list price, reset by /clear
Session time cost.total_duration_ms Wall-clock milliseconds
Lines changed cost.total_lines_added, cost.total_lines_removed
5-hour use rate_limits.five_hour.used_percentage 0–100. Pro and Max only, after the first reply
Weekly use rate_limits.seven_day.used_percentage Same rules
When they reset rate_limits.five_hour.resets_at, rate_limits.seven_day.resets_at Unix seconds
Folder workspace.current_dir workspace.project_dir is where you started claude
Effort effort.level Only on models that support effort
Open pull request pr.number, pr.review_state Only while one exists for the branch
Version version Handy when a feature "isn't there"

Several fields are missing until they apply (rate_limits, pr, effort, worktree, vim), and some are null before the first reply. A good script never assumes they exist.

What the cost figure means#

cost.total_cost_usd is worked out on your computer from token counts at list price. On an API key that's close to your bill; Anthropic still points to the Console's Usage page for the real number. On Pro or Max, Anthropic's cost docs say the session cost "isn't relevant for billing purposes" because usage is included in the plan. It's still a fair measure of how heavy a session was, and a quick way to spot one that's burning tokens.

A copy-paste status line script#

This one shows the model, context, session cost and, on a Pro or Max plan, how much of your 5-hour and weekly limits you've used. It needs jq, which you may have to install (brew install jq, sudo apt install jq).

Save it as ~/.claude/statusline.sh:

bash
#!/bin/bash
# Model, context, session cost and plan usage on one line.
export LC_ALL=C   # so printf reads 0.42 the same in every locale
input=$(cat)

MODEL=$(echo "$input" | jq -r '.model.display_name')
CTX=$(echo "$input" | jq -r '.context_window.used_percentage // 0' | cut -d. -f1)
COST=$(printf '%.2f' "$(echo "$input" | jq -r '.cost.total_cost_usd // 0')")
FIVE=$(echo "$input" | jq -r '.rate_limits.five_hour.used_percentage // empty' | cut -d. -f1)
WEEK=$(echo "$input" | jq -r '.rate_limits.seven_day.used_percentage // empty' | cut -d. -f1)

LINE="[$MODEL] context ${CTX}% | \$${COST}"
[ -n "$FIVE" ] && LINE="$LINE | 5h ${FIVE}%"
[ -n "$WEEK" ] && LINE="$LINE | week ${WEEK}%"
echo "$LINE"

Then:

  1. Make it executable: chmod +x ~/.claude/statusline.sh
  2. Add the statusLine entry from the section above, with "command": "~/.claude/statusline.sh".
  3. Send any message. The row reads like [Opus] context 8% | $0.42 | 5h 23% | week 41%.

We tested it against the sample JSON in Anthropic's docs, with and without the rate_limits block. The // 0 and // empty in each jq call are what keep it from printing null before the first reply, or on an API key where there are no plan limits.

Make the numbers change colour#

Wrap a number in ANSI codes to colour it. For example, to turn the 5-hour figure amber from 75% and red from 90%:

bash
if [ -n "$FIVE" ] && [ "$FIVE" -ge 90 ]; then FIVE="\033[31m${FIVE}\033[0m"
elif [ -n "$FIVE" ] && [ "$FIVE" -ge 75 ]; then FIVE="\033[33m${FIVE}\033[0m"; fi

Put it before the LINE= lines and print with echo -e "$LINE" so the codes are read.

Show your 5-hour and weekly usage#

The rate_limits object has a rolling five_hour window and a seven_day window, each with used_percentage and resets_at. Anthropic's docs put three conditions on it.

  • It appears only for Claude Pro and Max subscribers (or behind a Claude apps gateway with a spend limit).
  • It appears only after the first API reply in the session.
  • Each window can be missing on its own, and Claude Code drops a window once its reset time passes.

How each window starts and resets is in the 5-hour limit and weekly limit guides. For a one-off look rather than a permanent row, type /usage: it shows the same two bars plus what's using them (how to check Claude Code usage walks through that screen).

On Windows#

Claude Code runs status line commands through Git Bash when it's installed, otherwise through PowerShell. That has two consequences for the command string.

  • Write paths in command with forward slashes (C:/Users/you/.claude/statusline.ps1). In Git Bash, backslashes are eaten as escape characters and the command fails without a visible error.
  • To run a PowerShell script, call it through PowerShell: "command": "powershell -NoProfile -File C:/Users/you/.claude/statusline.ps1". It works whichever shell Claude Code picks.

When the status line doesn't show#

  • Nothing appears: run echo '{}' | ~/.claude/statusline.sh in a shell. If that prints nothing or fails, the script is the problem; chmod +x it and make sure it writes to stdout. claude --debug logs the script's stderr and its exit code.
  • It shows --, null or empty values: fields can be null before the first reply. Add fallbacks like // 0 and send a message.
  • It vanished after a settings change: if disableAllHooks is true in your own settings, Claude Code only runs a status line from managed settings. Organisations with allowManagedHooksOnly hide custom status lines too.
  • The context number differs from /context: the status line reports the last reply's counts, while /context adds an estimate for messages since. They agree again after the next reply.
  • tput cols gives the wrong width: the script's output is captured, not drawn straight to the terminal. Read the COLUMNS and LINES environment variables instead.

Several accounts? A status line shows one#

A status line reads one session, so it shows the one account that terminal is signed in to. If you have two Claude plans, the 5h 23% on screen says nothing about the other one, and nothing about the next reset that matters.

Shuriken shows all of them. In Settings › Sources, every account you added sits side by side with its 5-hour and weekly bars and when each resets, and the top bar shows how much you have left this week across all of them. How Shuriken reads each account once and shares the reading with every device is in every Claude account's limits on one screen. Only add accounts you own and are entitled to use; providers' terms may not allow sharing a subscription sign-in.

When you'd rather see every account than one, download Shuriken.

Sources

  1. Customize your status line (Claude Code docs) (accessed 22 October 2026)
  2. Commands (Claude Code docs) (accessed 22 October 2026)
  3. Manage costs effectively (Claude Code docs) (accessed 22 October 2026)

Frequently asked questions

How do I turn on the status line in Claude Code?

Run /statusline and describe what you want, for example "show model name and context percentage with a progress bar". Claude Code writes a script in ~/.claude/ and adds it to your settings. Or add a statusLine entry to ~/.claude/settings.json yourself.

Does the status line use tokens?

No. Anthropic's docs say it runs locally and doesn't consume API tokens. Your script only reads the JSON Claude Code hands it.

Why doesn't my status line show my 5-hour and weekly usage?

The rate_limits fields only appear for Claude Pro and Max subscribers, and only after the first reply in a session. On an API key or a cloud provider there is no plan bar to show.

Is the cost in the status line what I pay?

It is an estimate at list price, computed on your machine. On a Pro or Max plan your usage is included in the plan, so it shows how heavy the session was, not a bill.

How do I remove the status line?

Run /statusline and ask it to remove or clear it, or delete the statusLine entry from your settings.json.

Free tools