LLM cost calculator

Pro

A pricing calculator for LLM workloads. Set tokens per request, requests per day and prompt caching, and eight current models re-rank by monthly cost. Bars glide and prices roll as you drag.

Live · keyboard ready

Estimated monthly cost

Sample list prices per 1M tokens, October 2026

Input tokens
Output tokens
Requests per day
60% of input billed at the cache read rate
Input
$2,880
Cached
$432
Output
$1,125
Per request
$0.030

Claude Sonnet 5.5: $3.00 in, $0.30 cached, $15.00 out per 1M tokens.Sample prices for illustration, not a quote. Calculated in your browser, nothing was sent.

  • A pricing or settings page needs an honest monthly estimate for an LLM workload across several models.
  • People pick a model for a feature and should see how cost moves with prompt size, output length, traffic and caching.
  • An internal tool compares provider prices before a migration or a budget review.
  • Use model-picker to choose a model in a chat or composer without a cost comparison.
  • Use context-window to show the live token usage of one conversation against a model's context window.
  • Use usage-meter or usage-pricing for actual metered spend against a plan; this estimates, it does not report.

Installation

Pro source and install commands unlock with a Pro plan.

example.tsx
import { LlmCostCalculator, computeLlmCost, type LlmModelPrice } from "@/components/arc/llm-cost-calculator/llm-cost-calculator"; // With no props: eight current models at sample prices, RAG workload.export function PricingSection() {  return <LlmCostCalculator />;} // Your own price list, wired to your plan picker.const models: LlmModelPrice[] = [  { id: "claude-sonnet-5-5", name: "Claude Sonnet 5.5", provider: "Anthropic", mark: <ClaudeMark />, input: 3, cachedInput: 0.3, output: 15 },  { id: "gpt-6-luna", name: "GPT-6 Luna", provider: "OpenAI", mark: <OpenaiMark />, input: 0.25, cachedInput: 0.025, output: 3 },]; export function ModelBudget({ prices, onPick }) {  const [usage, setUsage] = useState({ inputTokens: 8000, outputTokens: 500, requestsPerDay: 20000, cached: true });  return (    <LlmCostCalculator      models={prices.data ?? models}      loading={prices.isLoading}      error={prices.error?.message}      onRetry={prices.refetch}      usage={usage}      onUsageChange={setUsage}      cacheHitRate={0.7}      description="List prices per 1M tokens, checked October 24, 2026"      onSelectedChange={(id, model) => onPick(model, computeLlmCost(model, usage, { cacheHitRate: 0.7 }))}    />  );}

API reference

2 parts. The first is the root.

LlmCostCalculator

A pricing calculator for LLM workloads in one panel. The header shows the selected model's monthly total in a large rolling figure. Below it, workload presets (Chat, RAG, Agent, Batch), three sliders for input tokens per request, output tokens per request and requests per day, and a Cached input switch that bills part of the input at the cache read rate. Every model sits in a ranked list, lowest cost first, with its real mark, a bar relative to the most expensive model and a rolling monthly cost; rows glide to their new rank as values change. Picking a row selects that model for the total and the footer breakdown (input, cached, output, per request) and its price line. With no props it compares eight current models at sample prices.

PropTypeDefaultDescription
modelsLlmModelPrice[]llmCostSampleModelsModels to compare. Each has an id, name, provider, an optional 16px mark, and prices in US dollars per 1M tokens: input, output and optional cachedInput (cache reads; without it cached tokens bill at the input price). An empty array shows the empty state.
usageLlmUsage–Controlled workload: { inputTokens, outputTokens, requestsPerDay, cached }. Pair with onUsageChange. Values between slider stops still compute exactly; the slider shows the nearest stop.
defaultUsageLlmUsagethe RAG preset (16,000 in, 500 out, 5,000 a day, cached)Starting workload when uncontrolled.
onUsageChange(usage: LlmUsage) => void–Called on every slider step, preset and cache toggle with the whole workload.
selectedstring–Controlled id of the selected model. Pair with onSelectedChange. An id that is not in models falls back to the cheapest model.
defaultSelectedstringthe second modelStarting selection when uncontrolled.
onSelectedChange(id: string, model: LlmModelPrice) => void–Called when someone picks a row by pointer or with the arrow keys.
presetsLlmUsagePreset[] | falsellmCostPresetsWorkload shortcuts shown as a segmented control, each { id, label, usage }. A Custom segment lights up when the sliders match no preset. Pass false to hide the row.
cacheHitRatenumber0.6Share of input tokens billed at the cached rate while Cached input is on, from 0 to 1. Shown beside the switch as a percentage.
daysPerMonthnumber30Days in a billing month.
loadingbooleanfalseShows placeholder rows with the list's exact geometry and disables the controls while prices load.
errorstring–Shows "Prices did not load" with this reason in place of the list. Pair with onRetry.
onRetry() => void–Adds a Try again button to the error state.
titlestring"Estimated monthly cost"Heading of the panel.
descriptionstring"Sample list prices per 1M tokens, October 2026"Line under the heading. Say where your prices come from and when they were checked.
notestring"Sample prices for illustration, not a quote. Calculated in your browser, nothing was sent."Fine print at the bottom of the panel.
classNamestring–Class on the root section.

computeLlmCost

The function the calculator uses, exported for server code, tests and invoices: computeLlmCost(model, usage, { cacheHitRate, daysPerMonth }) returns { input, cachedInput, output, total, perRequest } in dollars per month (perRequest per call).

No props.

Tab
Moves through the workload presets, the three sliders, the Cached input switch, the selected model row, then Try again in the error state.
Arrow leftorArrow right
On the presets, moves between workloads. On a slider, moves one stop.
Page uporPage down, Shift+Arrow
On a slider, moves two stops.
HomeorEnd
On a slider, jumps to the smallest or largest stop. In the model list, selects the cheapest or most expensive model.
Arrow uporArrow down
In the model list, selects the next or previous model by rank and moves focus with it.
Space
Toggles Cached input.
  • The panel is a section named by its heading. The model list is a radio group named "Models ranked by monthly cost, lowest first" with a single tab stop on the selected model.
  • Rows are in DOM order by rank, so a screen reader reads them in the order shown. Each row's name says the model, the provider, its rank and its monthly cost.
  • Sliders are Arc sliders with real values spoken as token and request counts, not stop indexes.
  • One polite status region announces the selected model's monthly cost and rank once the numbers settle (not on every drag frame) and says the prices are samples calculated in the browser.
  • Selection is shown by a tinted row, an accent bar and aria-checked, never by color alone in the accessible tree. The error state pairs an icon with the words Prices did not load.
  • The large total and the rolling numbers are hidden from assistive tech where the status region and row labels already carry the value.
  • Pointer focus draws no ring; keyboard focus uses Arc's shared focus ring.
  • Rows are placed by transform only and move to their new rank on a critically damped spring (about 240ms, no bounce), so a re-rank is one clean glide with no reflow.
  • Bars follow the same spring to their new share of the most expensive model.
  • Every price counts to its new value over 240ms on an ease-out with tabular numerals, written straight to the node so eight rows roll during a drag without re-rendering.
  • The model name under the total and the price line crossfade (100ms out, 160ms in) when the selection changes. State changes between loading, list, error and empty crossfade the list area at a fixed height.
  • Reduced motion jumps rows, bars and numbers to their end values and keeps every state and announcement. The loading pulse stops.
  • A container query stacks the sliders below 600px and, below 520px, moves the total under the heading, puts each bar on its own line under the model name (rows grow from 44 to 58px), and wraps the breakdown into two columns.
  • Monthly costs switch to compact figures ($420K, $4.2M) above $100,000, so the cost column never overflows; the total keeps every digit.
  • The presets scroll inside their own track if they ever outgrow the panel. Reads well from 320px to 720px; the panel caps at 720px.
  • Costs are pure arithmetic memoized per workload; a slider drag re-renders one small list.
  • Rolling numbers update text nodes from a motion value, not React state, and only transform, width and opacity animate.
  • The status announcement is debounced to 450ms so screen readers are not flooded during a drag. Nothing runs while the panel is idle.

Notes for AI

Give your coding assistant the Markdown reference instead of screenshots.

  • Use it on a pricing page, a model settings screen or a budgeting step where people need to see what a workload costs across models. Prices are inputs: pass your own models with current list prices and say where they came from in description.
  • The default prices are plausible samples for illustration, labeled as samples in the header and fine print. Do not present them as real quotes.
  • Prices are US dollars per 1M tokens. cachedInput is the cache read price; cacheHitRate decides what share of input bills at it while Cached input is on.
  • Keep marks 16px. Mono marks should use currentColor; the sample Claude mark is tinted with its brand color #D97757 and works in both themes.
  • Use computeLlmCost on the server for the same numbers the panel shows, for example to store an estimate with a plan.
  • Slider stops are fixed (250 to 200,000 input tokens, 100 to 16,000 output tokens, 100 to 1,000,000 requests a day). Controlled usage outside a stop still computes exactly.

The full library index for assistants is at /llms.txt.