LLM Usage Log Analyzer

Paste the usage log your app already produces -- one record per API call -- and see where the money went: spend by model, feature and day, your real cache hit rate, a 30-day run rate, and which levers would have saved something.

Bring your own rates. This tool does not fetch or assert any provider's price. Copy the per-million-token rates from each provider's own pricing page into the table below. Your log and rates are processed in this browser and are never uploaded.

Sizing a workload you have not run yet? Use the LLM API Pricing Calculator. Comparing a flat-rate coding plan against the API? See the AI Coding Plan vs. API Cost Calculator.

1. Your usage log

JSONL (one JSON object per line), a JSON array, or CSV with a header. Each record needs a model name and token counts. Understood: Anthropic-style usage (input_tokens, cache_read_input_tokens, cache_creation_input_tokens, output_tokens), OpenAI-style (prompt_tokens, completion_tokens, prompt_tokens_details.cached_tokens), and flat CSV columns of the same names. Optional: created_at or timestamp, and label or feature to group by feature.

2. Rates ($ per million tokens)

One row per model found in the log. A rate row matches any model id that starts with the name, so my-model covers my-model-20260101. Leave cached-input and cache-write blank to bill them at the input rate. Models without a rate are listed but not priced.

ModelInputCached inputCache writeOutput

Results

Paste a log and enter rates, then press Analyze.

What if a share of one model's traffic ran on another?

Same tokens, repriced. It says nothing about whether the cheaper model is good enough for the task.

Usage is optional, stays in this browser, and counts only analyses and copied summaries. No log contents, rates, identifiers, cookies, or analytics service are used. Uncheck to turn it off. Do Not Track and Global Privacy Control disable counting automatically.

Common questions

Where do I get a usage log to paste in?

Anything with one record per API call that carries the model name and the usage object the API returned. That can be your own request logging (one JSON object per line), a proxy or gateway export, or a CSV with columns such as model, input_tokens, output_tokens, cache_read_input_tokens, cache_creation_input_tokens, created_at and an optional label. Anthropic-style and OpenAI-style usage objects are both understood.

Does my log leave my browser?

No. Parsing and every calculation run in your browser; there is no server call. An optional anonymous local counter records which buttons get used, never the log or the rates, and it can be turned off.

Why do I have to type the rates?

Because a wrong price is worse than no price, and API pricing changes often. This page multiplies the tokens your log reports by the rates you paste in from each provider's own pricing page. It never fetches or asserts a vendor price.

How does it treat cached tokens?

It follows each API's own accounting. In an Anthropic-style usage object, input_tokens excludes cache reads and cache writes, which are separate buckets. In an OpenAI-style usage object, prompt_tokens includes the cached tokens, so the fresh part is the difference. Mixing these up double-counts cached tokens, which is the most common mistake in hand-built cost spreadsheets.

How trustworthy are the savings estimates?

They are upper bounds under stated assumptions, not forecasts. The cache estimate assumes your repeated prefix is long and stable enough to cache and ignores cache-write cost. The model-switch estimate reprices the same tokens and says nothing about whether the cheaper model is good enough for the task. Test any change on real traffic before relying on the number.

Switching models or editing a prompt rather than costing it? Diff saved outputs before and after to catch broken JSON, new refusals and truncation.