Context Meter
Show how full the model's context window is, with the exact token counts one press away.
Overview
A long conversation fills the model's context window, and what happens next, whether a reply fails or older messages are dropped, usually comes as a surprise. Context Meter shows the limit before it is reached: a small ring and a percentage, which open the exact numbers.
It counts nothing. used and limit are figures your model or tokenizer reported, and the meter does the division. It does not know your prices either, so cost is a string you have already formatted.
Anatomy
- TriggerA ring, the percentage when it is shown, and a warning mark near the limit
- DetailsThe popover the trigger opens
- BarThe share of the window in use
- CountsTokens used, the limit, and tokens left
- StatusNear the limit, or at it
- PartsWhat the tokens are made of, and the cost, when you pass them
- NoteYour own line of explanation
ContextMeter is one component. Installing context-meter brings Popover and the shared easing constants in lib/ease along as registry dependencies, and installs motion.
Behavior
Percentage
The percentage is used divided by limit, rounded down, so 99.6% reads as 99% and "100%" appears only when the window is full. Past the limit the real figure is shown, such as 104%, and the ring and the bar stay full.
A limit of zero or less shows 0%. Do not render the meter until you know the limit.
Motion
When used or limit changes, the ring, the percentage, and the bar glide from the old figure to the new one over 0.6 seconds, and the percentage counts through the values between. The status, and the name read by assistive technology, change at once. The meter does not animate when it first appears.
Ring only
Set showPercent to false to show the ring without the number, for a row with little room. The figure is still in the button's name and in the details.
Status
The meter has three states, reported as data-status on the trigger.
The meter reports the state. It does not say what your product does at the limit, because it cannot know. Use note to say it: that older messages will be summarized, or that the person should start a new conversation.
Parts and cost
parts lists what the tokens are made of. The meter shows the numbers you pass and does not check that they add up to used. cost adds one more row.
Placement
The trigger is sized to sit in a row of controls. In a Prompt Bar, pass it to actions.
Accessibility
The trigger is a button. Its name is the summary, such as "42% of context used", followed by the status when there is one. The ring and the visible percentage are hidden from assistive technology, so the figure is read once.
The warning is a mark and a phrase as well as a color, and the ring is drawn with the text color, so it holds up in forced colors.
With reduced motion, the ring, the percentage, and the bar change with no glide.
The details open in a popover that takes focus and closes on Escape, returning focus to the trigger. The bar has the meter role and is read as the token counts, not as a bare percentage.
The trigger is not a live region, so a change in the percentage is not announced. If crossing a threshold matters in your product, announce it yourself, once, when it happens.
Every string comes from labels, and labels.number formats every token count. The default formats numbers for English.
The preview has been checked with a keyboard and with axe. It has not been checked with a screen reader yet, and support for the meter role varies across them.
Installation
Usage
import { ContextMeter } from "@/components/ai/context-meter"
<ContextMeter used={usage.inputTokens} limit={model.contextWindow} />With the details filled in:
<ContextMeter
used={usage.inputTokens}
limit={model.contextWindow}
parts={[
{ label: "Messages", tokens: usage.messageTokens },
{ label: "Files", tokens: usage.fileTokens },
]}
cost={formatCurrency(usage.cost)}
note="When the window fills, the oldest messages are summarized."
/>Examples
In a Prompt Bar
The meter in the bar's actions, starting near the limit. Sending a prompt adds a sample count to it.
Ring only
The meter with showPercent set to false. The button adds sample tokens, so the ring can be seen moving.
API reference
ContextMeter
Accepts native button props beyond those listed.