AI
Usage meterAIPro
Token and credit usage: a segmented bar against a limit, a context window ring that warns near the limit, and a monthly summary strip.
npx prodular-ui add usage-meterPart of Prodular UI Pro. Preview and read the docs freely, install with a license. See pricing
Token usage
Input, output and cached tokens against the monthly limit. The total turns to a warning at 80%.
- Input1.42M
- Output610K
- Cached880K
Resets November 1. Cached input is billed at a tenth of the input rate.
- Input1.16M
- Output420K
- Cached196K
89% used with 10 days left. Replies will pause at the limit.
import { UsageMeter } from "@/components/ui/usage-meter"
export default function UsageMeterTokens() { return ( <div className="mx-auto flex w-full max-w-lg self-start flex-col divide-y rounded-xl border bg-card shadow-xs"> <UsageMeter className="p-4" label="Ledger assistant" limit={5_000_000} segments={[ { label: "Input", value: 1_420_000 }, { label: "Output", value: 610_000 }, { label: "Cached", value: 880_000 }, ]} description="Resets November 1. Cached input is billed at a tenth of the input rate." /> <UsageMeter className="p-4" label="Support automation" limit={2_000_000} segments={[ { label: "Input", value: 1_160_000 }, { label: "Output", value: 420_000 }, { label: "Cached", value: 196_000 }, ]} description="89% used with 10 days left. Replies will pause at the limit." /> </div> )}Context window
The ring fills as the conversation grows and changes color near the limit. Drag the slider. The compact ring explains itself in a tooltip.
"use client"
import * as React from "react"
import { Slider } from "@/components/ui/slider"import { ContextWindow } from "@/components/ui/usage-meter"
export default function UsageMeterContextWindow() { const [used, setUsed] = React.useState(96_400) const max = 128_000
return ( <div className="flex w-full max-w-md flex-col gap-6"> <ContextWindow variant="full" used={used} max={max} /> <div className="flex items-center gap-3 border-t pt-4"> <span className="text-[13px] text-muted-foreground">In a toolbar</span> <ContextWindow used={used} max={max} /> <span className="ms-auto w-40"> <Slider aria-label="Tokens in context" min={0} max={max} step={800} value={used} onValueChange={(v) => setUsed(Array.isArray(v) ? v[0] : v)} /> </span> </div> </div> )}Monthly credits
A bar and one summary strip with dividers, not a grid of cards.
October credits
Growth plan, 25,000 credits a month
import { Button } from "@/components/ui/button"import { UsageMeterBar, UsageSummary, UsageSummaryItem } from "@/components/ui/usage-meter"
export default function UsageMeterCredits() { return ( <div className="mx-auto flex w-full max-w-2xl self-start flex-col gap-4 rounded-xl border bg-card p-4 shadow-xs"> <div className="flex items-center justify-between gap-3"> <div> <h3 className="text-sm font-medium">October credits</h3> <p className="text-[13px] text-muted-foreground">Growth plan, 25,000 credits a month</p> </div> <Button variant="outline" size="sm"> Buy credits </Button> </div> <UsageMeterBar limit={25_000} segments={[ { label: "Agents", value: 11_240, color: "chart-1" }, { label: "Insights", value: 4_880, color: "chart-2" }, { label: "Suggestions", value: 2_300, color: "chart-3" }, ]} /> <UsageSummary> <UsageSummaryItem label="Used" value="18,420" description="74% of plan" /> <UsageSummaryItem label="Remaining" value="6,580" description="About 9 days at this rate" /> <UsageSummaryItem label="Top consumer" value="Agents" description="11,240 credits, 61%" /> <UsageSummaryItem label="Resets" value="Nov 1" description="In 11 days" /> </UsageSummary> </div> )}Anatomy
<UsageMeter label="Ledger assistant" limit={5_000_000} segments={[ { label: "Input", value: 1_420_000 }, { label: "Output", value: 610_000 }, { label: "Cached", value: 880_000 }, ]}/><ContextWindow used={96_400} max={128_000} />Guidance
Use it when
- Show usage where people spend it: the context ring in the composer, the token meter on the feature's settings, credits on the billing page.
- Split the bar into the segments people pay for differently, such as input, output and cached tokens.
- Say what happens at the limit in description: replies pause, older turns are summarized, overage is billed.
- Put the period and reset date next to monthly numbers.
Avoid
- Percentages without the absolute numbers. Show 1.42M of 5M tokens.
- Red before the limit is actually reached. Warning starts at warnAt, destructive only when exceeded.
- A grid of KPI cards for the summary. Use UsageSummary, one strip with dividers.
Rules for AI agents
Published in llms-full.txt and the registry, so coding agents follow them when they build with this component.
- Pass raw numbers (tokens or credits as integers) and let the component format them. Do not pass preformatted strings to UsageMeter or ContextWindow.
- Always pass limit to UsageMeter and max to ContextWindow from the real plan or model. Update ContextWindow max when the selected model changes.
- Use ContextWindow variant="compact" in toolbars and variant="full" in panels. Never hide the ring once the context is above warnAt.
- Keep tabular-nums on any number you render next to these components so values do not shift as they update.
- Use chart-1 to chart-5 or muted for segment colors. Never use AI gradient colors for usage, it is not generated content.
API
UsageMeter
| Prop | Type | Default | Description |
|---|---|---|---|
| label | ReactNode | What is being measured. | |
| segments | { label: string; value: number; color?: "chart-1" | ... | "chart-5" | "muted" }[] | Parts of the total, in order. | |
| limit | number | The plan limit. Exposed with data-state ok, warning or exceeded. | |
| warnAt | number | 0.8 | Ratio of the limit where the warning starts. |
| unit / format / description | string / (n) => string / ReactNode | "tokens" / formatTokens | Unit label, number formatting and a line under the bar. |
ContextWindow
| Prop | Type | Default | Description |
|---|---|---|---|
| used / max | number | Tokens in context and the model's window. | |
| variant | "compact" | "full" | "compact" | compact is a 16px ring with a tooltip, full shows numbers and a status line. |
UsageSummaryItem
| Prop | Type | Default | Description |
|---|---|---|---|
| label / value / description | ReactNode | One cell of the summary strip. |