Field SOP
Field SOP

Migration SOP for Model Sunsets and Repricing: Four Steps to Inventory, Migrate, Recalculate, and Contain Cost

Three things happened at once on 2026-08-31: Sonnet 5 API rates moved from $2 and $10 to $3 and $15, GPT-5.4 and GPT-5.4 mini stopped being offered to Codex users signed in with ChatGPT, and kimi-k2.5 and moonshot-v1 sunset the same day. The three change types need completely different responses, yet most teams apply one uniform reaction and end up either overreacting or underreacting. This SOP runs four steps. Step zero classifies using keywords in the vendor announcement: sunset or deprecated means the ID stops responding, handle it today; replace or a default change means the entry point still works but the model behind it changed, so run a regression this week; pricing only means no interruption but a recalculation this month. Step one inventories every model ID in the codebase with a single grep, collapses them into one central config, and wires the check into CI. Step two executes the per-type migration. Step three recalculates monthly cost from three factors: tokenizer inflation, peak versus off-peak share, and cache hit rate. Also included: an eleven-item checklist, step four on limits, alerts and a fallback path, and seven ways this goes wrong, the most common being model IDs scattered through code where one fix misses three call sites.

Published August 31, 202612 min read
<!-- model-sunset-migration-cost-sop | sop | Migration SOP for Model Sunsets and Repricing: Four Steps to Inventory, Migrate, Recalculate, and Contain Cost -->

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.

TypeSymptomUrgencyConsequence of inaction
SunsetOld model ID stops respondingImmediate, same dayCalls fail outright; outage
ReplacementRoute still works, model behind it changedThis weekBehaviour and output shift; regression needed
RepricingID unchanged, unit price changedThis monthCost 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:

bash
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.txt

Do 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:

ts
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 const

The 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:

text
monthly cost ~= input_tokens * tokenizer_factor * input_price * (1 - cache_hit_rate)
              + input_tokens * tokenizer_factor * cache_price * cache_hit_rate
              + output_tokens * output_price

One 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:

  1. Scan the repository for model IDs, including env files, config, and runtime data; produce an inventory
  2. Tag each ID with status (in use / deprecated / pending migration) and an expiry date
  3. Consolidate IDs into one configuration and wire an expiry check into CI
  4. Sunsets: switch today; confirm regional pricing first, run regression after
  5. Replacements: choose one path, accept and re-test, or move to API key auth
  6. Schedule the known dates: 09-14, 10-10, 10-24, 11-12, 11-21
  7. Measure your tokenizer factor against real corpus
  8. Move asynchronous work into off-peak windows
  9. Log cache-hit token counts and alert on hit rate
  10. Split cost per model; alert on daily cost and spikes
  11. 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.

This article is AI-assisted and human-edited. Last updated: 2026-08-31

FAQ

Model IDs are scattered across dozens of files. How do I find them all at once?
Sweep for candidates with one grep, then confirm by hand: grep -rnE "(gpt-|claude-|kimi-|moonshot|qwen|deepseek|glm-|doubao|gemini|grok|mimo)" scoped with --include for your file types. Do not edit each hit. Collapse them into one central config 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.
After migrating, do prompts need re-tuning?
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.
How do I estimate the post-migration bill before I ship?
Use three factors. 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.
How do I notice a cache hit rate regression?
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.
What counts as an acceptable fallback path?
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.

Related

Field SOP

DeepSeek V4.1 Flash Integration SOP: Five-Step Migration

A five-step SOP for taking DeepSeek V4.1 Flash into production: (1) decide what should and should not migrate - leave production paths that depend on quirky legacy-model behavior alone for now; (2) a pre-migration checklist - inventory every config, env var and hardcoded string where the model name appears, and prepare a representative prompt set as a regression baseline; (3) the five migration steps - switch the model name to deepseek-flash (centrally managed, not scattered hardcoding), run a minimal verification script, diff outputs against the old model with attention to format stability and instruction following, roll out gradually behind a rollback switch, then watch failure rate, retry rate and output-length distribution; (4) tie it to agent workloads by comparing token consumption before and after the switch on the same batch of long-trajectory tasks, verifying the claimed KV Cache compression yourself rather than taking launch copy at face value; (5) six pitfalls and a ten-item launch checklist. Every price, rate limit and window figure is marked "refer to the official documentation" rather than invented.

Sep 10, 202611 min read
Field SOP

GPT-Live-1 Realtime Voice API Integration SOP

A five-step SOP for taking OpenAI's GPT-Live-1 real-time voice API into production: (1) fit and non-fit - real-time phone voice agents and voice customer service versus local batch dubbing (see the same-batch VoiceStudio for the latter); (2) a pre-integration checklist - permissions and quota, inventory of text-pipeline changes, a regression baseline, and whether backend strong-model hand-off is needed; (3) the five integration steps - centralize auth and credentials (no hardcoded keys), a minimal runnable real-time voice script (WebSocket/HTTP skeleton with auth, session creation, audio-frame send/receive), integration with the business pipeline (feed recognition results to logic, re-inject backend output into synthesis), a backend strong-model hand-off design (when to call GPT-5.6 Sol / GPT-6 Astra and how to meter cost), then gradual rollout and monitoring (concurrency, duration distribution, retry, cost alerts); (4) voice-agent specifics - regression testing for interruption handling and noise robustness, and the state-management complexity of full duplex; (5) seven pitfalls and a ten-item launch checklist. Every price, rate limit and concurrency ceiling is marked "see official docs" rather than invented.

Sep 13, 202611 min read
Field SOP

Build Long-Running Agent Workflows with GPT-6 Astra

A hands-on SOP for building long-running agent workflows on GPT-6 Astra's real capabilities (1.05M context, 128K output, 0% alignment overreach): start with three prerequisites (OpenAI Python SDK 1.50+, the OPENAI_API_KEY environment variable, and API allowlist), then proceed in order through long-context planning, tool definition (function calling plus computer use), async invocation, mid-flight correction, and acceptance with cost control. Key points: on the first call place only the goal, acceptance criteria, tool list, and key background so the model emits a plan first; tools must specify name, description, and parameters; use streaming events plus a background queue and task-id polling for async; correct course by injecting new instructions without restart; and accept only via independent assertion scripts while keeping max_output_tokens small and setting a daily spend cap.

Sep 4, 202611 min read