Status line
statusline prints one short line for status bars:
llm-usage statusline$270.20 today · 6d streak · ~$1,215.82 this monthThe line shows today’s cost, the current streak (left out at zero), and month-to-date cost. A ~ marks a cost that leaves out unpriced events; a day without any known cost shows its token count instead. With monthlyBudgetUsd in the config file, the month reads ~$1,215.82/$2,000.00 this month, followed by ⚠ once spending or the month-end projection passes the budget.
It is built for frequent refreshes:
- pricing is never fetched: it uses cached LiteLLM prices, or the bundled snapshot when there is no cache. The cache only refreshes when another report runs online, so if you use only the status line, a model released after your installed version stays unpriced until you run a report such as
llm-usage daily. With a custompricing.urlin the config, run any report online once so that URL’s prices are cached; until thenstatuslineexits with an error - the update check is skipped, and nothing is printed on
stderr; errors still exit non-zero. Add--verboseto see the warnings it hides, and runllm-usage doctorif refreshes feel slow (an unusable event store means every run reparses all files). One exception: the first run that finds no usage logs at all prints a one-time hint onstderr - parsed events come from the event store, so repeat runs only reparse changed files
- runs that overlap share a lock file next to the event store (
events.db.statusline.lockbeside the defaultevents.db). A run that finds the lock held waits up to a second, then printswarming up…instead of parsing the same files again. On a first run over large logs, the tick holding the lock parses and the others printwarming up…until it finishes. A lock left by a run that exited, or older than two minutes, is taken over by one of the runs that find it; the others wait as for a held lock
It accepts the source, provider, model, machine, timezone, cost-mode, pricing-override, and history flags of the other reports, so a status line can show one tool only:
llm-usage statusline --source claudeA filtered line shows no budget, since the budget covers all your usage.
The line uses cached or bundled prices and other machines’ cached usage, and prints nothing on stderr unless you pass --verbose. So statusline has no --json, --quiet, --pricing-url, --pricing-offline, or --no-sync. For structured data, use llm-usage summary --json.
Claude Code
Section titled “Claude Code”Add a statusLine command to ~/.claude/settings.json:
{ "statusLine": { "type": "command", "command": "llm-usage statusline" }}Claude Code passes the session’s details on stdin, and the line then starts with the session’s cost and how full its context window is:
$1.23 session · 42% context · $270.20 today · 6d streak · ~$1,215.82 this monthBoth numbers come from Claude Code as it sends them: the session cost is Claude Code’s own estimate at list price and resets with /clear, so it can differ slightly from the same usage in llm-usage reports. Either part is left out until Claude Code has a value for it, such as before the first reply. Other status bars pass nothing on stdin. If a bar leaves stdin open, each run waits a quarter second for input that never comes. The wait overlaps building the line, but a warm run that would take 0.1 s takes 0.3 s. Add </dev/null to the command for such a bar:
llm-usage statusline </dev/nullset -g status-interval 60set -g status-right '#(llm-usage statusline)'starship
Section titled “starship”[custom.llm_usage]command = "llm-usage statusline"when = trueshell = ["sh"]starship runs custom commands on every prompt, and a warm run takes a few hundred milliseconds, so raise command_timeout if the module disappears, or prefer tmux or the Claude Code status line for a line that refreshes on its own.