Three things landed on the same day, 2026-08-31. Claude Sonnet 5's API rate returned from $2 and $10 to the standard $3 and $15. GPT-5.4 and GPT-5.4 mini stopped being served in Codex to users signed in with a ChatGPT account. Moonshot AI sunset kimi-k2.5 and moonshot-v1. These three changes need completely different responses, and most teams apply one generic response to all of them, ending up either over-reacting or under-reacting. This piece gives a four-step procedure: classify, inventory, migrate, then recalculate metering and add monitoring.
Scope note: facts here come from aitoolsrecap's 2026-08-31 summary, the Tencent AI daily brief for 2026-08-31, TheRouter.ai's provider pricing and deprecation notices retrieved 2026-08-24, and a pricing table compiled by checking each vendor's official pricing page individually (checked 2026-08-24, re-checked 2026-08-28). Prices are a 2026-08-31 snapshot and move frequently; verify against the official pricing page and announcements for your own account region. Commands and configuration samples are generic illustrations and need adapting to your stack. For migration targets, follow vendor announcements; no unverified substitution is recommended here.
Step 0: classify which kind of change you are dealing with
This step gets skipped most often, and it sets the priority for everything after it. The three kinds differ entirely in urgency.
| Type | Symptom | Urgency | Consequence of inaction |
|---|---|---|---|
| Sunset | Old model ID stops responding | Immediate, same day | Calls fail outright; outage |
| Replacement | Route still works, model behind it changed | This week | Behaviour and output shift; regression needed |
| Repricing | ID unchanged, unit price changed | This month | Cost rises; no outage |
Today's three events map cleanly onto the three types. kimi-k2.5 and moonshot-v1 are sunsets and must be handled today. GPT-5.4 leaving Codex is a replacement: nothing errors, but the model answering you has changed, so regression testing is required. Sonnet 5 returning to standard pricing is a repricing: no interruption, but costs need recalculating.
Treating them alike wastes effort in both directions. Reading a repricing as a sunset triggers an unnecessary emergency migration; reading a sunset as a repricing means you find out when production starts erroring. The test is simple: look for two words in the vendor announcement. Sunset or deprecated means retirement. Replace or a default change means replacement. Pricing alone means repricing.
Step 1: inventory, and pull model IDs out of the codebase
Most teams only discover at the first sunset that they cannot say how many model IDs they use or which services hold them. Fix that first.
Scan the whole repository. Run one recursive search matching the common model-name prefixes, excluding dependency directories:
grep -rnE "(gpt-|claude-|kimi-|moonshot|qwen|deepseek|glm-|doubao|gemini|grok|mimo)" \
--include="*.ts" --include="*.tsx" --include="*.py" --include="*.js" \
--include="*.json" --include="*.yaml" --include="*.yml" --include="*.env*" . \
| grep -v node_modules | grep -v ".next" > model-inventory.txtDo not stop at source. Model IDs routinely hide in three places that get missed: default model values in environment files, fallback chains in configuration, and historical session records stored in databases or caches. The last category is the worst, because it is runtime data: changing code does not fix it, and you need a migration script.
Then build a registry with an expiry-date field. Collapse scattered strings into one configuration, shaped roughly like this:
export const MODELS = {
chat: {
id: 'kimi-k3',
provider: 'moonshot',
sunset: null,
migratedFrom: 'kimi-k2.5',
note: 'Migrated from k2.5 on 2026-08-31; verify pricing for your account region',
},
reason: {
id: 'deepseek-v4-pro',
provider: 'deepseek',
sunset: '2026-10-24',
migratedFrom: 'deepseek-reasoner',
note: 'Peak/off-peak: weekdays 09-12 and 14-18 are peak, off-peak is half',
},
cheap: {
id: 'gpt-5.6-luna',
provider: 'openai',
sunset: null,
migratedFrom: null,
note: 'High-throughput simple tasks; permanent price 0.20 / 1.20 USD',
},
} as constThe value here is not elegance. It is that expiry becomes an explicit field. With it, the next announcement means editing one line rather than hunting strings across the codebase. Wire it into CI while you are there: a check that fails the build when a model ID past its sunset date is referenced beats any documentation reminder.
Step 2: migrate, one procedure per change type
Sunsets: switch now, and verify. kimi-k2.5 and moonshot-v1 sunset today with kimi-k3 as the target. The switch itself is one ID, but two things come first. Confirm the new ID's price in your own account region, since reported kimi-k3 figures vary considerably (some sources quote $3 and $15, others RMB 20 and 100), and do not budget off someone else's invoice. Then run a regression pass, because a new model means a new output distribution, and anything downstream that parses responses needs retesting.
Replacements: pick one of two paths. GPT-5.4 leaving Codex affects users signed in with a ChatGPT account, with GPT-5.6 Terra ($2 and $12) and Luna ($0.20 and $1.20) taking over. You can either accept the new model and re-test, or switch to API key authentication to keep using the original. The first costs less effort but carries behavioural change; the second is stable but pulls key management into your secrets infrastructure. Decide by measuring how far apart the two models are on your core tasks. Test, do not guess.
Schedule the already-announced dates in one pass. The published calendar: 2026-09-14 Claude Code permanent weekly limits take effect; 2026-10-10 DashScope retires 30-plus legacy IDs including qwen-turbo, qwen-vl-plus, qwen-audio-turbo, and several early Qwen3 snapshots; 2026-10-24 deepseek-chat and deepseek-reasoner are deprecated; 2026-11-12 OpenAI models leave Cursor; around 2026-11-21 GPT-5.6 Sol's promotion ends and $4 and $20 revert to $5 and $30. Put all of them in the schedule now rather than during announcement week.
Step 3: recalculate metering, three factors drive the real invoice
After migration, the new bill is not comparable to the old one, because the unit of measurement may have shifted. Three factors need recomputing.
Factor one: tokenizer inflation. Sonnet 5 changed tokenizers, mapping identical input to 1.0x to 1.35x as many tokens depending on content type. No official breakdown by content type exists, so the reliable approach is to take your own corpus and count it under both tokenizers to get your real factor. It costs almost nothing and beats every estimate.
Factor two: peak and off-peak windows. DeepSeek has billed peak and off-peak since 2026-08-17: weekdays 09:00-12:00 and 14:00-18:00 are peak, off-peak is half, weekends are off-peak all day. Schedule anything asynchronous into off-peak windows. That is a 2x spread requiring no engineering change. Do not budget against stale figures either: the 2026-08-13 GA note recorded uncached input at 3 and output at 6 RMB, but after the peak/off-peak reform, peak moved to 9 and 27.
Factor three: cache hit rate. Platforms charge far less for input tokens that hit a prefix cache, in some models a small fraction of the standard input rate. This variable is yours to move. Putting stable system instructions at the very front and reusing history prefixes across turns raises hit rates directly. Log cache-hit token counts separately, or you will never know how much discount you are collecting.
Combine the three into a reusable monthly estimate:
monthly cost ~= input_tokens * tokenizer_factor * input_price * (1 - cache_hit_rate)
+ input_tokens * tokenizer_factor * cache_price * cache_hit_rate
+ output_tokens * output_priceOne caution: the input-to-output ratio moves the result substantially, because output is typically priced three to five times input. Any budget built on a rough "half and half" assumption needs redoing against your real ratio. Worked examples and how the ranking shifts are in this batch's comparison piece: /en/posts/post-aug31-token-cost-comparison-review.
Step 4: monitor and contain, limits, alerts, and a fallback path
Know the limit changes in advance. Anthropic has announced a permanent 25 percent increase to Claude Code weekly limits effective 2026-09-14, with the current 50 percent temporary boost holding until 09-13. Indexed across three points: the pre-May baseline is 100, today is 150, and from September 14 it is 125. That is plus 25 percent against the old standard and minus 17 percent against what you have now. If you rely on Claude Code weekly capacity for heavy work, the boost still applies until September 13, and capacity will be lower than today afterwards, so plan throughput accordingly.
Alert per model, not in aggregate. Set at least three: daily cost per model against a budget threshold, week-over-week token spikes per model, and cache hit rate falling below expectations. The third is the one everyone skips, and a falling hit rate usually means someone restructured a prompt, quietly doubling cost without a single error.
Build the fallback path before you need it. The cheapest model is not found by shopping; it is found by splitting traffic. GPT-5.6 Luna at $0.20 input and $1.20 output has a blended cost of $0.70, roughly one thirteenth of Sonnet 5. Moving high-throughput simple work such as classification, extraction, formatting, and routing off a flagship usually saves more than switching vendors, and it does not touch quality where it matters.
A checklist you can copy
In execution order:
- Scan the repository for model IDs, including env files, config, and runtime data; produce an inventory
- Tag each ID with status (in use / deprecated / pending migration) and an expiry date
- Consolidate IDs into one configuration and wire an expiry check into CI
- Sunsets: switch today; confirm regional pricing first, run regression after
- Replacements: choose one path, accept and re-test, or move to API key auth
- Schedule the known dates: 09-14, 10-10, 10-24, 11-12, 11-21
- Measure your tokenizer factor against real corpus
- Move asynchronous work into off-peak windows
- Log cache-hit token counts and alert on hit rate
- Split cost per model; alert on daily cost and spikes
- Stand up a fallback route to a cheap model for simple tasks
Seven ways this goes wrong
Reading the rate card and ignoring tokenization. The easiest trap in this cycle. Sonnet 5's rate rose 50 percent, but code workloads land 65 to 100 percent higher once the tokenizer change is compounded. What you feed it determines what you pay.
Modelling promotions as permanent. GPT-5.6 Sol's $4 and $20 reverts to roughly $5 and $30 around 2026-11-21, moving the blended cost from $12 to $17.5. Any migration with engineering cost should be justified at the post-expiry rate; three months of savings rarely pays for the work.
Model IDs scattered through the code. Fixing one call site and missing three is the most common direct cause of migration incidents. Centralised configuration plus a CI check solves it once.
Ignoring the input-to-output ratio. Output costs three to five times input, so any 1:1 estimate can be far off the real bill.
Not monitoring cache hit rate. It is a silent variable. It does not error when it drops; it shows up on the month-end invoice.
Mixing subscription quotas with API costs. This Sonnet 5 change affects API pricing only; consumer subscriptions are unaffected. The two cost bases are not comparable on one sheet.
No fallback path. Discovering there is no cheap model to fail over to when you need to cut spend leaves only two options: degrade everything or absorb the cost. Build the fallback while costs are healthy.
One closing note on cadence. This round looks dense, but taken apart, every item came with lead time: Sonnet 5's standard price was stated in the launch pricing documentation two months ago, Claude Code's limit change was announced half a month ahead, and the DashScope October retirement leaves a six-week window. What catches teams out is never the announcement itself; it is treating model IDs as permanent rather than as dependencies that expire. Build the registry from step one, wire it into CI, and every future announcement becomes a one-line change.
FAQ
Q1: Model IDs are scattered across dozens of files. How do I find them all at once?
A1: Sweep for candidates with one grep, then confirm by hand: grep -rnE "(gpt-|claude-|kimi-|moonshot|qwen|deepseek|glm-|doubao|gemini|grok|mimo)" --include="*.ts" --include="*.py" --include="*.json" --include="*.yaml" . Do not edit each hit. Collapse them into one central config (see the MODELS example in step one) and have application code reference constants only. Then wire that same grep into CI as a failing check, so the next hardcoded ID gets caught before it merges.
Q2: After migrating, do prompts need re-tuning? A2: Yes, but calibrate the effort. Same-vendor, same-family upgrades (kimi-k2.5 to kimi-k3, for example) usually need no prompt rewrite, only a regression pass. Cross-vendor moves (DeepSeek to GLM, say) require a full regression over prompts and tool-call schemas. The part most often missed is tokenization: the same prompt costs a different number of tokens under a different tokenizer, which moves both cost and context budget. Measure it once before and once after and the difference is quantified.
Q3: How do I estimate the post-migration bill before I ship? A3: Use the three factors from step three. Tokenizer inflation: run the same sample through both tokenizers and take the ratio. Peak versus off-peak share: what proportion of your load can actually be scheduled off-peak. Cache hit rate: measured on production traffic, not assumed. Monthly cost is roughly input tokens times the inflation factor times the input rate times (1 minus hit rate), plus the cached portion, plus output tokens times the output rate. Substitute a default for any one of the three and the estimate drifts.
Q4: How do I notice a cache hit rate regression? A4: It never throws an error; it shows up on the invoice at the end of the month, so it has to be monitored deliberately. Log cached read and written token counts per call, aggregate hourly into a hit rate, and alert on a threshold, for example twenty points below baseline. The most common cause is not on the model side at all: someone put a timestamp, a request ID, or retrieval fragments in random order into the prompt prefix, which destroys prefix matching.
Q5: What counts as an acceptable fallback path? A5: Three conditions. First, the cheaper alternative is integrated and passes regression while costs are healthy, not on the day you need to cut spend. Second, switching is a one-line config change, not a code change and a release. Third, degraded output has an acceptable floor: if falling back makes the feature unusable, that is not a fallback, it is an outage. Note also that this Sonnet 5 change affects the API only and leaves Consumer subscriptions untouched, which is a reminder that the two quota types need separate fallback designs.