Control the bill
Seeing where the tokens go is only the first half; acting on it is the second. /cost shows what you've spent and /context shows what's in the conversation right now, while an optional spend cap stops a turn before it crosses your budget.
Two views, reconciled
Squeezy keeps two parallel accounts of every turn, and shows you both. The provider account is what the API billed: input tokens, output tokens, the slice of output that was reasoning, the input served cheaply from cache, and the input written into cache the first time. The local account is Squeezy's own deterministic estimate of the request it assembled, broken down by what each part of the conversation contributes.
Why both? The provider account tells you the bill was high but not what to cut. The local breakdown tells you which part of the conversation is large but misses the cache discount and the reasoning surcharge. Together they let you see the charge and the reason for it on the same screen. Cutting tokens without measuring them is guessing; this layer measures first.
What Squeezy tracks per turn and per session
On every assistant turn Squeezy records a tally and folds it into the running session total. The categories map directly to how providers bill, so the numbers line up with your invoice rather than a single opaque “tokens used” figure.
- Input tokens: the size of the prompt the model saw, uncached, cached, and cache-write input combined into one comparable number.
- Output tokens: everything the model generated, billed at the output rate.
- Reasoning: the portion of output that was the model thinking rather than visible text. On most providers this is pure cost, so it's worth seeing on its own.
- Cached input: prompt prefix served from the provider's cache at a discount, a healthy number here is proof that prompt caching is working.
- Cache-write input: the first pass that seeds the cache. Some providers don't separate this from a normal miss, so it may not appear for them.
- Dollar estimate: a USD figure derived from the token counts and local pricing, shown where Squeezy has pricing for the model.
/cost, spend so far
Run /cost for the cumulative picture of the session. It names the session, provider, model, and mode, then prints the estimated dollars spent and the provider-reported token counters. Where work happened, it also rolls up tool-call counts, sub-agent spend, deduplication hits, and any denials, and when a session spent across more than one model it adds a per-model breakdown so you can see which model carried the cost. When turns were routed to a cheaper model, /cost also shows the savings: the spend alongside a baseline, meaning what that same work would have cost on the always-strong headline model. That savings line is a counterfactual estimate from token counts, not a measured charge.
Squeezy is deliberate about what this is: the token counters are provider-reported when the provider reports them, and the dollar figure is an estimate from local pricing, not a billing authority. It's meant for steering decisions in the moment, not for reconciling an invoice to the cent.
/cost /context, what's in the window and where the space goes
Run /context to see the current conversation laid out by where its space is going. At the top it shows how much of the context window is consumed and how much headroom remains, as a token count and a percentage, with the headroom colored so a nearly full window is obvious at a glance.
Below that is the consumption-by-source breakdown, the part that makes the bill actionable. It splits the assembled request into user and assistant text, tool-call output, reasoning, images, attached context, and the system prompt. The breakdown always reconciles to the consumed total, so you can see whether tool output, a big attachment, or the conversation itself is eating your window. When one source dominates, /context adds a short recommendation pointing at the knob that would help.
This is the view that turns a vague “my context is filling up” into a specific decision. If tool output is half your window, that's a verbosity problem; if attachments dominate, that's a detach. The number you see here is the same number the automatic compaction trigger watches, so what you read and what Squeezy acts on are never different figures.
/context A live panel, a cold-shell CLI, and an offline export
/cost is a one-shot snapshot; for a running readout without leaving the transcript, toggle the live cost panel (Ctrl+X B by default). It refreshes on the same cadence as the rest of the TUI's status polling and shows the session's per-mechanism savings alongside a cross-session per-provider/model rollup, worded out as "saved" or "cost" rather than a bare +/- sign.
Outside a running session, squeezy savings reads the same durable ledger from a cold shell: a per-mechanism, per-provider/model, or time-bucketed (hourly/daily/weekly) breakdown, in text, JSON, or CSV. squeezy perf complements it with the cross-session tool-loop waste report. Both open the state store directly, so neither needs a live TUI or agent instance.
squeezy savings --export-html <path> writes a self-contained static HTML report (tables and dependency-free bar charts, no JavaScript or external resources) for sharing or archiving outside a terminal.
squeezy savings --by time --time-bucket daily
squeezy savings --by mechanism --format csv
squeezy savings --export-html cost-report.html
squeezy perf --json Bounding the bill, not just watching it
Seeing the spend is always on; stopping it is something you turn on. If you set a session cost cap or a per-round input-token ceiling, Squeezy treats them as hard limits: before it starts the next provider round it checks the running total, and if that round would cross your number the turn stops with a clear reason instead of quietly spending past it. As the session approaches the cap you get a single heads-up rather than a surprise at the end.
Both limits are unset by default, so out of the box Squeezy reports but never blocks, the readouts above are the always-on part and the ceiling is the part you opt into. They sit with the other budgets in project settings, so a team can commit one ceiling and have every checkout inherit it.
[budgets]
max_session_cost_usd_micros = 5000000 # stop the session at ~$5.00 of estimated spend
cost_warn_percent = 85 # warn once at 85% of the cap
max_round_input_tokens = 200000 # refuse a round whose input would exceed this What depends on the provider
Some figures are only as complete as what the provider reports. Token counters fill in as Squeezy receives usage events from the API. Cache-write input doesn't exist on every provider, so it can read as zero where the provider doesn't distinguish a first cache write from an ordinary miss, and Squeezy won't invent a cost line it can't substantiate.
The per-source breakdown in /context is a deterministic local estimate of the request content, not a re-derivation of the provider's exact tokenizer count, accurate enough to steer by, and it self-corrects turn over turn as Squeezy reconciles its estimate against the provider's input count.
How this lets you trust and tune the other layers
This layer is the substrate the rest of the cost-saving work stands on. The cached-input line is how you confirm prompt caching is paying off, and it stays meaningful even when a turn is routed to a cheaper model, because that cheap work runs in its own isolated scope so the main model's warm cache isn't cold-rewritten. The per-source breakdown is what makes the verbosity controls useful. The consumed percentage is what compaction reads to decide when to fire. Every other lever becomes a decision you can make on evidence instead of a hunch, you read /context, see tool output is the largest bucket, turn down tool verbosity, and the next /context shows the window drop.