Skip to content

Pricing

llm-usage-metrics uses LiteLLM pricing data to estimate costs when events do not include explicit cost. For the design behind these knobs (the fallback ladder, model-name matching, and the cost engine), see the Pricing Pipeline deep dive.

  • primary source: LiteLLM pricing JSON
  • cache: online runs use a fresh cache first, then refresh from LiteLLM when needed
  • fallback: stale cache is used when live refresh fails
  • bundled snapshot: the default LiteLLM pricing URL can fall back to a bundled snapshot
  • offline mode: --pricing-offline skips network and uses cache, stale cache, or the bundled snapshot
  • retired models: LiteLLM eventually drops retired models (for example claude-sonnet-4-20250514); their last published prices are bundled and back-fill the default source, so historical usage stays priced. A retired price is dropped when a live LiteLLM key prices the same names at the same rates (including names with a release or effort suffix or a provider prefix, but not misspellings that only fuzzy matching reaches), so those names follow that live key, which may be a reseller’s, until the next snapshot refresh re-checks them
Terminal window
llm-usage monthly --pricing-offline

When the bundled snapshot is used, stderr includes a warning with the snapshot date:

Pricing: using the bundled LiteLLM snapshot from 2026-10-15 (run online to refresh).

Online runs refresh a stale cache; omitting --pricing-offline can still use a fresh cache. A cache past its refresh interval is still used when the refresh fails or the run is offline, and stderr then names the cache date (and the fetch error, when a refresh was attempted):

Pricing: the LiteLLM refresh failed (network timeout); using cached pricing from 2026-07-01.

Custom --pricing-url values do not fall back to the bundled default snapshot; they must load from their matching cache or network URL.

When pricing.offline = true is set in the config file, there is no --no-pricing-offline flag; force a one-off online refresh by bypassing the config for that run (LLM_USAGE_CONFIG_PATH=/nonexistent llm-usage monthly) or edit the config.

For cache lifecycle and tuning knobs, see Caching.

llm-usage pricing <model...> shows how each model name you give resolves to the prices the cost engine applies. It never reads usage, so it works on a machine with no session logs. Pass names as they appear in your logs, or in a report’s model column:

Terminal window
llm-usage pricing claude-sonnet-4-5 gemini-2.5-pro --pricing-offline
claude-sonnet-4-5
Normalized claude-sonnet-4-5
Pricing key claude-sonnet-4-5
Rule direct
Override none
Prices from bundled LiteLLM snapshot from 2026-10-15 (https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json)
Input $3.00 / 1M
Output $15.00 / 1M
Cache read $0.30 / 1M
Cache write $3.75 / 1M
Cache write 1h $6.00 / 1M
Reasoning billed as output
gemini-2.5-pro
...
Above 200,000 input $2.50 / 1M, output $15.00 / 1M, cache read $0.25 / 1M, cache write $0.25 / 1M

For each name it prints:

  • Normalized: the name as the matcher sees it, trimmed and lowercased.
  • Pricing key: the LiteLLM key whose prices apply, or unpriced when nothing matched.
  • Rule: how the matcher reached the key. direct is an exact key, possibly after dropping a provider prefix (anthropic/claude-sonnet-4-5 reads direct (as claude-sonnet-4-5)). The others are the model map’s preferred key, effort suffix dropped, provider-prefixed key, key plus a release suffix, and fuzzy with its edit distance. A name the model map rewrites first reads model map to <model>, then <rule>.
  • Override: whether a --pricing-overrides entry applies, keyed on the name or on its pricing key.
  • Prices from: the bundled snapshot, the pricing cache or a fresh fetch, with its date and URL, or the overrides file. An unpriced name shows Searched instead, naming what was searched.
  • Retired: present when the prices come from models LiteLLM no longer lists.
  • Rates per 1M tokens for input, output, cache read, cache write and one-hour cache write. not listed means LiteLLM gives no rate for that bucket; as cache write means one-hour writes bill at the cache-write rate.
  • Above N: each long-context tier, highest threshold first. When any name has tiers, the report ends with a line saying they apply only to events that record one request.
  • Priority rates: the buckets priced at a priority rate because LiteLLM lists no standard one.

The command takes --pricing-offline, --pricing-url, --pricing-overrides, --quiet, --json and --markdown. Exit status is 0 even for an unpriced name, so check pricingKey in the JSON. --json returns { models } under data; each model row has model, normalizedModel, pricingKey, rule, canonicalModel, strippedModel, fuzzyDistance, override, origin, retired, rates, tiers and priorityFallback, as described in report-pricing.v1.schema.json.

Use it when a report marks a model with ~ or -, when a cost looks off, or to check that an override file entry is picked up:

Terminal window
llm-usage pricing my-internal-model --pricing-overrides ./pricing-overrides.json

Each event is either:

  • explicit: source included a valid cost
  • estimated: cost derived from pricing data

--cost-mode picks which of these costs a report uses:

  • both (the default): the logged cost when the source has one, otherwise an estimate. An event that logged $0 but used tokens is estimated from LiteLLM when the model has pricing. Unless --cost-mode was passed, stderr then says how many shown events that affected and which sources logged them.
  • explicit: logged costs only. A logged $0 stays $0, and events without a logged cost stay unpriced, so totals are marked ~ and the stderr note counts the events with no logged cost. LiteLLM pricing is not loaded to price events. Reports that need prices beyond event costs still load it: optimize for its candidate models, and summary, statusline and wrapped for the cache-savings estimate. --pricing-url, --pricing-offline and --pricing-overrides apply to those prices.
  • estimated: every event is priced from its tokens and logged costs are ignored. An event that cannot be priced is left unpriced (~) rather than shown with its logged cost.

--cost-mode cannot be combined with --no-cost.

Claude caches a prompt for five minutes or one hour, and a one-hour write costs more (2x the input rate instead of 1.25x). Claude logs record how many written tokens used each lifetime, so one-hour writes are priced at LiteLLM’s one-hour rate. Models without a one-hour rate, and events stored before 0.10.2 whose log file is gone, price every write at the standard cache-write rate. When history has two stored copies of such a file, one from before the upgrade, it may serve the older copy at that rate.

Some models charge more for a request with a long prompt. Claude Haiku 5.5 bills a prompt over 100,000 tokens at higher rates, Gemini 2.5 Pro over 200,000, and GPT-5.4 and later over 272,000. LiteLLM lists these as *_above_<N>k_tokens rates, and the bundled snapshot and the pricing cache keep them as tiers.

  • A request’s prompt is its input, cache read and cache write tokens together. When the prompt is strictly over a tier’s threshold, the whole request bills at that tier: input, output, cache reads, cache writes and one-hour cache writes. When several thresholds are crossed, the highest one wins. A bucket the tier gives no rate bills at its base rate.
  • Tiers apply only to events that record one request (singleRequest in events output): every event from claude, gemini, pi, opencode and antigravity, and codex events that Codex logged per response (0.153 and later) or whose change in running totals equals the row’s last_token_usage. Other events can sum several requests: droid and goose log session totals, and a codex delta that spans several responses covers all of them. Those bill at base rates rather than crossing a threshold on a total.
  • optimize prices candidate models on each period’s totals, which are not requests, so it uses base rates. It prices your actual usage, the baseline, at base rates too, so a tier premium never shows up as savings. Its baseline cost can therefore be lower than the cost the other reports show for the same period.
  • The threshold is always strict (>). LiteLLM’s own calculator treats xAI thresholds as inclusive (>=), so a prompt of exactly the threshold can differ there.
  • The estimated cache savings in summary and wrapped use the same per-event rates.
  • Service-tier variants (_batches, _priority, _flex and similar) and LiteLLM’s tiered_pricing ranges are not used.
  • --pricing-overrides entries carry no tiers, so an overridden model bills at its flat rates.

Pricing caches written before tiers existed are discarded once: with the default pricing URL, the next run fetches fresh pricing, and if the fetch fails or the run is offline it uses the bundled snapshot instead of the old cache. A custom --pricing-url keeps using its old cache until a refresh succeeds, since it has no bundled snapshot to fall back on.

An older and a newer llm-usage that share one pricing cache (for example a global install that runs statusline and an npx run of a later version) each treat the other’s cache as out of date. An online run then refetches pricing and rewrites the cache whenever the other version wrote it last, rather than once a day. Updating both to the same version stops it.

When LiteLLM lists only a priority rate (*_priority) for a model’s input, output, cache read or cache write, that rate prices that bucket. stderr counts the events that have tokens in such a bucket; an event of the same model that uses only standard-priced buckets is not counted:

2 events priced at LiteLLM priority rates because no standard rate is listed (models: minimax-m2p7)

--quiet and --no-cost hide that line.

  • - when all contributing events are unresolved
  • ~$... when only part of the row cost is known
  • $... when row cost is fully resolved

When any cost is marked ~, stderr names how many of the shown events have no known price and their models. --quiet and --no-cost hide that line.

Terminal window
llm-usage monthly --pricing-url https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json

A JSON file of per-model rates takes precedence over LiteLLM pricing. Use it for internal/custom models, negotiated rates, or values you want to correct.

Terminal window
llm-usage monthly --pricing-overrides ./pricing-overrides.json

Illustrative file shape (these are example rates, not a provider rate card):

{
"models": {
"my-internal-model": { "inputPer1MUsd": 1, "outputPer1MUsd": 2 },
"my-cached-model": {
"inputPer1MUsd": 12,
"outputPer1MUsd": 60,
"cacheReadPer1MUsd": 1.2,
"cacheWritePer1MUsd": 18.75
}
}
}

Only inputPer1MUsd and outputPer1MUsd are required; cacheReadPer1MUsd, cacheWritePer1MUsd, cacheWrite1hPer1MUsd, reasoningPer1MUsd, and reasoningBilling are optional. cacheWrite1hPer1MUsd prices one-hour cache writes (Claude); without it they bill at cacheWritePer1MUsd. reasoningBilling: "included-in-output" (the default) bills all output tokens at outputPer1MUsd; "separate" bills the reasoning share of output at reasoningPer1MUsd and only the remainder at outputPer1MUsd, since outputTokens already includes reasoning. Rates must be finite, non-negative numbers. A missing required rate, an invalid rate, an unknown key, or an unknown reasoningBilling value fails the run with an error naming each bad entry, so a typo never leaves a model silently priced from LiteLLM. Model names match case-insensitively, and an override on a name short-circuits LiteLLM alias resolution for that name.

An override has no long-context tiers, so every request of an overridden model bills at the file’s rates.

Overrides can price a model absent from your current cache or bundled snapshot, or select rates for a specific workload. The DeepSeek Harness guide explains refreshed pricing, legacy model names, and peak versus off-peak estimates.