LLM Price Volatility: 49 Models Repriced in 12 Days (Your Cost Table Has a Shelf Life)
On 2026-07-29 we re-fetched the full live model catalog and diffed it against the snapshot we took on 2026-07-17. In those twelve days, of roughly 396 models, 49 changed price and 57 were newly listed. Prices moved in both directions, and input and output rates did not always move together — one model raised its input rate 18% while cutting its output rate 15% in the same change. That is about one model in eight repricing inside two weeks. Every LLM cost estimate anyone publishes, including ours, is a token count multiplied by a list price on a particular day. If an eighth of the catalog reprices that fast, a cost table with no capture date is not a fact. It is a rumour with decimal places.
Nobody publishes this, so we ran it. Two full catalog captures, 12 days apart, diffed row by row. The result is a number that quietly invalidates most of the LLM cost content on the internet, including some of ours.
What an 12-day catalog diff actually found
We took a full capture of the live model catalog on 2026-07-17 and another on 2026-07-29. Between them, out of roughly 396 models:
- 49 models changed price. That is about one in eight, in 12 days.
- 57 models were newly listed. A separate axis of churn — those rows have no before value at all.
- Prices moved in both directions. This is not a story about everything getting cheaper.
- Input and output rates did not always move together. One model raised input and cut output in the same change, which flips the direction of the move depending on how output-heavy your workload is.
That last point is the one that breaks spreadsheets. A blended rate — the single dollar figure most cost pages quote — hides a change that can be positive for a summarisation workload and negative for a classification workload at the same time.
The named movers, before and after
Six of the 49 changes, checked by hand against both captures. Rates are list prices per 1M tokens, shown to the cent as the catalog publishes them, and the percentage columns are computed from the figures shown — a sub-cent rounding can shift a delta by a few tenths of a point. The last column is the combined rate for a hypothetical 1M input plus 1M output — a single-number summary that lets you rank the moves, not a claim about your token mix.
| Model | 2026-07-17 in / out | 2026-07-29 in / out | Input Δ | Output Δ | Combined 1M+1M Δ |
|---|---|---|---|---|---|
| DeepSeek V4-Flash | $0.09 / $0.18 | $0.14 / $0.28 | +55.6% | +55.6% | +55.6% |
| GLM-5 | $0.60 / $1.92 | $0.95 / $2.55 | +58.3% | +32.8% | +38.9% |
| Qwen3.7-Max | $1.25 / $3.75 | $1.48 / $4.42 | +18.4% | +17.9% | +18.0% |
| Qwen3 Coder Next | $0.11 / $0.80 | $0.12 / $0.80 | +9.1% | 0% | +1.1% |
| Kimi K2.6 | $0.55 / $3.20 | $0.65 / $2.72 | +18.2% | −15.0% | −10.1% |
| GLM-5.2 | $0.93 / $3.00 | $0.72 / $2.27 | −22.6% | −24.3% | −23.9% |
Read the DeepSeek V4-Flash row and the GLM-5.2 row together. In the same twelve days, one cheap model got 56% more expensive and another got 24% cheaper. Anyone who wrote a cost comparison on 2026-07-17 ranking those two has a page that is now wrong in a way no reader can detect, because the page does not say when it was priced.
Kimi K2.6 is the awkward one. Input up 18.2%, output down 15.0%. If you send long prompts and get short answers, that is a price rise. If you send short prompts and generate long documents, it is a price cut. A single blended number cannot represent it, and neither can a leaderboard.
Qwen3 Coder Next barely moved — input up one cent per million, output flat. It is in the table precisely because it shows the spread of magnitudes inside those 49 changes. Some are rounding, some are 58%.
What this does to one of our own measured numbers
Abstract volatility is easy to nod along to. Here is what it does to a figure we published.
Our executed coding benchmark measured DeepSeek V4-Flash at $0.13 per 1,000 tasks, priced at list prices of 2026-07-17 — 9/9 on nine executed Python tasks, 14.5 s mean latency, 568 reasoning tokens. That number is correct and it is now stale.
DeepSeek V4-Flash went from $0.09 / $0.18 to $0.14 / $0.28. Both rates moved by the same factor, 1.556. When both rates move by the same factor, the recomputed cost scales by that factor exactly, whatever the input/output split happened to be. So the same token counts, on the same nine tasks, would cost about $0.20 per 1,000 tasks at 2026-07-29 prices. We did not re-run it. We re-priced it.
GLM-5.2 moved the other way. Measured at $1.99 per 1,000 tasks, priced 2026-07-17. Its input rate fell 22.6% and its output rate fell 24.3% — different factors, so the exact recompute depends on the token split. It has to land between $1.51 and $1.54 per 1,000 tasks at 2026-07-29 prices. That is a bound, not a point, and we would rather publish the bound than invent the precision.
| Model | Measured cost / 1k tasks pricedAt 2026-07-17 | Same token counts at 2026-07-29 prices | Change | Exact or bounded |
|---|---|---|---|---|
| Qwen3 Coder Next | $0.10 | $0.10 to $0.11 | 0% to +9.1% | Bounded · output flat, input +9.1% |
| DeepSeek V4-Flash | $0.13 | about $0.20 | +55.6% | Exact · both rates moved by 1.556 |
| GLM-5.2 | $1.99 | $1.51 to $1.54 | −22.6% to −24.3% | Bounded · input −22.6%, output −24.3% |
Two things worth pulling out of that table.
The repricing did not change any ranking. DeepSeek V4-Flash was the second-cheapest model in our core 13-model sweep at $0.13; at $0.20 it is still second-cheapest, because the next model up is DeepSeek V4-Pro at $0.74 priced 2026-07-17. A 56% cost increase moved nothing on the leaderboard. That is exactly why price volatility is easy to miss — the ordinal ranking looks stable for months while your actual bill moves by half. If you are budgeting, the ranking is not the number you care about.
Not every number rots at the same speed. Qwen3 Coder Next barely moved. Publishing one refreshed figure and leaving the others alone would be worse than useless, which is why the honest unit of maintenance is the whole capture, not the one row somebody complained about.
The full run those figures come from is in the LLM coding cost benchmark, and the arithmetic on your own token mix is in the cost calculator.
Where we are exposed, and what we changed
This site publishes cost tables. That makes us a defendant here, not a commentator. So, plainly:
Our benchmark stores a pricedAt date per model. Every row in our results file carries the date its list price was captured, not just the dollar figure. The core 13-model sweep is stamped 2026-07-17. Gemini 3.6 Flash was run and priced 2026-07-28. Seven more models were run and priced 2026-07-29. Across all 21 models on the same harness, 18 scored 9/9 — but the costs in that set are not all denominated on the same day, and the file says so per row rather than letting one date stand for everything.
Our sidebar prices are generated, not hand-copied. A script reads the catalog dump and writes a dated price file; the page build reads that file and never touches the catalog directly. So every page can state when its prices were captured, and a refresh is a rebuild rather than a hand edit across 200 files. Retired model ids are listed explicitly and fail the build rather than silently rendering a stale price — Grok 4, Grok 3, Grok 3 Mini and Grok Code Fast 1 are in that list and are never priced as callable.
The catalog dump is not exhaustive, and we treat it that way. Grok 4.5 was listed publicly and was still absent from our 2026-07-17 catalog snapshot. Absent from the dump never means does not exist, so hand-verified prices go in an override table with the source URL and the date they were checked. The build will not delete a price just because it failed to resolve one.
We changed the harness to record raw token counts. The runner now stores prompt tokens, completion tokens and reasoning tokens for every call, alongside the computed cost. That is the difference between a number that can be recomputed at any future price and a number that rots. It is also why the DeepSeek figure above is a point estimate and the GLM-5.2 figure is a range: our published summary file carries the cost and the pricedAt date but not the per-model input/output split, so an outside reader can rescale exactly only when both rates moved by the same factor.
Older cost figures in our archive were computed at earlier prices. They are labelled with the date they were priced, and we are not going back to silently overwrite them. An article that says $0.13 per 1,000 tasks, priced 2026-07-17 is telling you the truth about 2026-07-17. An article that says $0.13 per 1,000 tasks with no date is telling you nothing you can check. We would rather be visibly out of date than invisibly wrong.
One thing we will not do is claim these are billed costs. Our cost figures are measured token counts multiplied by a list price on a stated date. They are not invoices. Method and boundaries are on the methodology page.
Build a cost estimate that survives a repricing
The fix is structural, not clerical. Six rules:
1. Store token counts, not dollars. Log prompt tokens, completion tokens and reasoning tokens per call. Dollars are a view over that data, computed at render time against a current price table. If your logs contain only dollars, you have thrown away the only durable half of the measurement and you can never recompute.
2. Put a capture date on every price you store. A price without a date is not data. This applies to your internal spreadsheet as much as to anything you publish.
3. Re-read list prices on a schedule. One in eight models moved in 12 days in our window. Weekly is defensible for most teams. If you are spending enough that a 56% rate change matters within a billing cycle, run it daily.
4. Alert on change, do not just log it. A diff that writes to a file nobody opens is a diff that does not exist. Route it somewhere a human reads — the whole value is in noticing within days rather than at the end of the quarter.
5. Watch delistings, not only reprices. A retired model id is a hard failure at request time, not a budget surprise. Treat disappearance from the catalog as a higher-severity event than a price move.
6. Treat any third-party pricing page without a capture date as unreliable. Not malicious — unreliable. The author may have been careful on the day they wrote it. You have no way to know which day that was, and roughly an eighth of the catalog has moved since then if it was more than a fortnight ago.
If your spend sits inside an agent loop, the same repricing hits every call in the loop at once — the compounding arithmetic is in what AI agents actually cost, and the current cheap tier is in the cheapest LLM APIs of 2026.
A price-diff script you can run on a schedule
This is the whole mechanism. It fetches the current list prices, compares them against a stored snapshot, and prints what moved. Under 40 lines, no dependencies.
// price-watch.mjs — fetch live list prices and diff them against a stored snapshot.
// node price-watch.mjs prices-2026-07-17.json
import fs from 'node:fs';
const SNAP = process.argv[2] ?? 'prices.json';
const per1m = v => Math.round(Number(v) * 1e6 * 1e4) / 1e4; // catalog quotes $ per token
const live = {};
const res = await fetch('https://openrouter.ai/api/v1/models');
for (const m of (await res.json()).data) {
const p = m.pricing || {};
if (p.prompt == null || p.completion == null) continue; // free / unpriced rows
live[m.id] = { in: per1m(p.prompt), out: per1m(p.completion) };
}
const old = fs.existsSync(SNAP)
? JSON.parse(fs.readFileSync(SNAP, 'utf8'))
: { capturedAt: null, prices: {} };
const changed = [], added = [], delisted = [];
for (const [id, p] of Object.entries(live)) {
const o = old.prices[id];
if (!o) { added.push(id); continue; }
if (o.in !== p.in || o.out !== p.out) changed.push({ id, from: o, to: p });
}
for (const id of Object.keys(old.prices)) if (!live[id]) delisted.push(id);
console.log(`since ${old.capturedAt}: ${changed.length} repriced, `
+ `${added.length} new, ${delisted.length} delisted, ${Object.keys(live).length} total`);
for (const c of changed)
console.log(`${c.id} $${c.from.in}/$${c.from.out} -> $${c.to.in}/$${c.to.out}`);
for (const id of delisted) console.log(`DELISTED ${id}`); // hard failure, not a price move
// Overwrite the snapshot deliberately, never automatically. A baseline that silently
// updates itself destroys the very thing you are diffing against.
if (process.env.WRITE_SNAPSHOT === '1')
fs.writeFileSync(SNAP, JSON.stringify({
capturedAt: new Date().toISOString().slice(0, 10), prices: live
}, null, 1));
Three details that matter more than the code. The snapshot is only overwritten behind an explicit environment flag, because a baseline that refreshes itself on every run can never report a change. Prices are normalised to per-1M tokens at fetch time, so a change in the catalog's own units does not read as a price move. And delistings are printed separately from reprices, because they are a different class of problem: one costs you money, the other returns an error.
Point the same script at whichever catalog you actually buy through. The endpoint changes; the pattern does not.
What this diff does not tell you
It is two snapshots, not a time series. We compared 2026-07-17 against 2026-07-29 and counted net change. A price that rose and fell back inside those twelve days reads as unchanged. The real number of price events is at least 49 and could be higher.
It is one catalog. These are the list prices on a single public aggregator. Direct-from-vendor pricing, committed-spend discounts, cached-input rates, batch rates and enterprise agreements are not in this diff and can move independently.
Both counts are floors. The catalog dump is not exhaustive — we know it omitted at least one publicly listed model in the 2026-07-17 capture. So 49 repriced and 57 newly listed are lower bounds on what actually happened.
We named six movers, not 49. The other 43 changes are in the diff and are not written up here. We are not claiming the six are representative; they are the ones we verified by hand because they appear in our own benchmark and price file.
One window is not a rate. Roughly 12% of the catalog repricing in 12 days is what we observed once. It is not a stable weekly churn rate and we are not going to present it as one until we have run the diff over several months.
Our recomputed figures are re-priced, not re-run. The $0.20 and the $1.51 to $1.54 above hold the measured token counts fixed and change only the price. If a vendor ships a new version behind the same model id, the token counts change too and the only honest move is to re-run the benchmark.
Price your own workload against today's rates
One OpenAI-compatible endpoint, 300+ models, one key. Swap the model id, log the token counts, and recompute the cost whenever the price list moves.
FAQ
How often do LLM API prices actually change?
In the one window we measured, 49 of roughly 396 models changed price in 12 days — about one in eight — and 57 more were newly listed. That is a single observation between our 2026-07-17 and 2026-07-29 captures, not a stable rate. It is also a floor: two snapshots count net change, so a price that moved and moved back inside the window is invisible to the diff.
Do prices only go down over time?
No. In this diff they moved in both directions. DeepSeek V4-Flash rose 55.6% on both input and output. GLM-5 rose 58.3% on input. GLM-5.2 fell about 24%. Kimi K2.6 raised input 18.2% while cutting output 15.0% in the same change, so whether it got cheaper for you depends on how output-heavy your workload is. The long-run trend in the industry has been downward; that says nothing about what your specific model did last fortnight.
Are your published benchmark costs still accurate?
They are accurate as of the date each one was priced, and every row carries that date. The core 13-model sweep is priced 2026-07-17, Gemini 3.6 Flash 2026-07-28, and seven later models 2026-07-29. DeepSeek V4-Flash measured $0.13 per 1,000 tasks priced 2026-07-17; the same token counts at 2026-07-29 prices come to about $0.20. We label rather than overwrite, because a figure with a date can be checked and a figure without one cannot.
How do I stop my cost model from going stale?
Store token counts rather than dollars, so cost is a view computed at render time. Attach a capture date to every price you store. Re-fetch the list prices weekly, diff against the previous snapshot, and route the diff somewhere a human reads. Treat a delisted model id as a higher-severity event than a price change, because it fails at request time rather than at month end.
Why can you recompute one model exactly and only bound another?
Because it depends on whether input and output rates moved by the same factor. DeepSeek V4-Flash went from $0.09/$0.18 to $0.14/$0.28 — both by the same factor, 1.556x — so the recomputed cost scales by 1.556 regardless of the token split. GLM-5.2 fell 22.6% on input and 24.3% on output, different factors, so without the per-model input/output split the answer is a range: $1.51 to $1.54 per 1,000 tasks. Our runner records those raw token counts; the published summary file currently carries the cost and the pricedAt date instead.
Should I trust a pricing page that has no capture date?
Treat it as unreliable rather than wrong. The author may have been accurate the day they wrote it, but you cannot tell which day that was, and roughly an eighth of the catalog moved inside twelve days in our window. The same test applies to us: if a cost figure on this site appears without the date it was priced, that is a defect, not a style choice.
DataLLM Lab