Model Deprecation & Migration

9 min read

O10
Operation · AgentOps: Deploy & Operate

Model retirement: you shipped a dependency with an expiry date, and it is not in your lockfile.

Every model ID in your codebase will be switched off on a date somebody else picks, and the notice you get is measured in weeks to months — Anthropic commits to a minimum of 60 days for publicly released models, and some platform retirements have landed with far less. The mistake is filing this under maintenance. A replacement model is a different system with different failure modes, so a migration is a re-qualification, and that notice window is your entire regression-testing budget. Teams that discover this when the email arrives spend it panicking; teams that rehearse it spend a day.

STEP 1

The dependency you cannot vendor.

Every other dependency in your stack has an escape hatch. A library goes unmaintained and you pin the last good version forever; a package registry goes down and you serve from a mirror; a vendor raises prices and you keep running what you already have. A hosted model has none of these. When the retirement date passes, requests to that model ID fail, and there is no copy on disk to fall back to.

That makes it a genuinely unusual dependency and it deserves unusual handling:

  • It expires on someone else's schedule. You have no vote, and the date is set by the economics of serving old weights, not by your release calendar.
  • It cannot be frozen. "We'll upgrade next quarter" is available for every library you use and for none of your models.
  • Its replacement is not equivalent. A patched library keeps its contract. A newer model does not — that is the entire reason it exists.
  • The blast radius is behavioural, not structural. Nothing fails to compile. The agent simply starts doing something slightly different, which is far harder to notice.

Model IDs deserve the same treatment as a pinned version in a lockfile, with one addition a lockfile does not have: an expiry. Keep an inventory — every model ID, where it is used, which team owns it, and the announced retirement date — and treat a missing entry as a build-time failure. If you cannot list your model IDs in under a minute, your migration has already started badly.

STEP 2

Notice windows, and why the shortest one sets your schedule.

Providers do publish policies, and they are not unreasonable. Anthropic commits to notifying customers with active deployments at least 60 days before retirement of a publicly released model, with a documented lifecycle — Active, Legacy, Deprecated, Retired — and email plus documentation notice at each transition. OpenAI publishes a deprecations page and gives longer windows to foundational models than to specialised snapshots. The policies are real and worth reading in full, once, from the provider's own page rather than a summary.

Two things about them nonetheless bite in practice:

  • The floor is the number that matters. A 60-day minimum is a commitment about the worst case, and you should plan against the worst case, because the model you will regret is the one that gets the minimum. Sixty days sounds generous until you subtract the two weeks before anyone reads the email, the sprint the work lands in, and the fact that the replacement needs a full eval cycle.
  • Consumer-facing and marketplace timelines are separate. A model retired from a chat product is not necessarily retired from the API, and the same model offered through a cloud marketplace carries that marketplace's dates, not the lab's. If you consume a model through a reseller, the reseller's schedule is your schedule.

The planning consequence is a standing assumption rather than a calendar entry: assume that at least one model in your stack enters retirement every quarter. Once you accept that, migration stops being a project that interrupts the roadmap and becomes a recurring operation with a rehearsed runbook, which is the only version of this that scales.

STEP 3

A migration is a re-qualification, not a string replacement.

The change itself is one line. Everything expensive is downstream of it, because you are not upgrading a component — you are swapping the thing that decides what your agent does. Expect all four of these to move:

  • Prompt sensitivity. Instructions tuned against one model's quirks are, at best, neutral on the next one. The few-shot examples that fixed a formatting problem may now be the thing causing it. Anything phrased as a workaround for a specific failure is a candidate for deletion, not translation.
  • Tool-calling behaviour. Schema strictness, willingness to call in parallel, appetite for retrying a failed call, tendency to invent an argument rather than ask — all of these differ by model and none of them is in the release notes. This is the layer where agent migrations actually break.
  • Step count and cost. A stronger model that finishes in eight steps instead of twenty is cheaper per completed task even at a higher token price, and a chattier one is more expensive even at a lower one. Re-derive unit economics from measured trajectories, not from the price list.
  • Latency and caching. Different tokenisation, different throughput, and a cache that starts cold. Your p95 will move on the day of the swap for reasons that have nothing to do with quality; see prompt caching.

Because all four move together, the only honest gate is your eval suite run as a paired comparison — same tasks, same seeds, old model against new, in the same batch. Anything less and you are attributing noise to the migration or, worse, missing a real regression inside it. The statistics for this are in eval variance and statistical power, and the mechanism belongs in the same gate you already use for rollout and versioning.

Budget for the possibility that the replacement is worse for your workload. It happens, particularly when a general-purpose successor replaces a model you had tuned around, and the answer is not to argue with the retirement date. It is to have found out early enough to evaluate a second candidate — possibly from another provider — while you still had weeks rather than days.

STEP 4

Auto-upgrade: the migration nobody chose.

Some platforms do not merely retire a model; they move you. Azure has force-upgraded standard deployments at retirement — when two 2024 snapshots of GPT-4o reached their retirement date in March 2026, those deployments were automatically moved to a current model rather than left to fail. From a platform-availability standpoint this is the kind option. From an agent-operations standpoint it is the worst possible outcome, because it converts a loud failure into a silent behaviour change.

Think about which one you would rather debug. A hard failure produces an error, an alert, and a stack trace pointing at a model ID. An auto-upgrade produces a Tuesday on which your agent's tool-calling behaviour shifted, your evals were not run, and nobody has a hypothesis. The second costs more even though it involved no downtime.

  • Find out which of your deployments can be moved without your action. This is a per-platform, per-deployment-type question, and the answer is usually in the pricing tier — reserved or provisioned capacity is often treated differently from standard.
  • Prefer explicit failure where the choice exists. A request that errors on a retired model is a better outcome than one silently served by a different model, because the first is an incident with a known cause.
  • Alert on the model identifier in the response, not just the one in your config. Providers echo back what actually served the request. If that field changes and no deploy of yours caused it, you want to know within minutes. This is a cheap check and almost nobody has it.
  • Route through a layer you control. A gateway or a routing layer means the model ID lives in one place, and swapping it is a config change with a flag rather than a redeploy. See model routing and feature flags for agents.
STEP 5

The standing drill.

The teams that handle retirements in a day are not smarter about models; they have built three things in advance, none of which is exotic.

  • An inventory that is generated, not maintained. Grep the codebase and the config store for model identifiers on every build and fail the build on one that is not in the registry. A hand-maintained list is wrong within a month, and the model ID in a forgotten batch job is exactly the one that will bite.
  • A candidate lane that is always warm. The suite should be runnable against any model ID by changing one parameter, and it should be run against the current successor on a schedule — monthly is enough — whether or not a retirement is pending. Then the notice email finds you with a recent, paired result already in hand, and the migration is a decision rather than a project.
  • A rehearsed swap. Flip the flag to the new model for 5% of traffic, watch the trajectory metrics and the cost per completed task, and be able to flip back in seconds. If your rollback for a model change is a redeploy, you do not have a rollback. See online vs offline evals for what to watch during the ramp.

One more thing belongs in the runbook because it is invisible until it is not: the replacement has a different knowledge cutoff. Anything in your prompts that compensated for the old model's temporal blind spot — an injected current date, a hard-coded "as of" caveat, a retrieval step that existed only to cover recent events — needs re-checking, and so does anything that quietly relied on the old cutoff being where it was.

STEP 6

What to do this week.

The full drill in Step 5 takes a quarter to build. Three things take an afternoon and remove most of the exposure:

  • Produce the inventory once, by hand if necessary. Every model ID, every place it appears, one owner per entry. Most teams find at least one they did not know about — a batch job, an eval judge, an embedding model, a fallback path that has not run since it was written.
  • Check every entry against the provider's own deprecations page today. Not a summary, not a blog post, not this page: the vendor's live list, which is the only authoritative one and which changes. Write the announced retirement date next to each ID.
  • Make sure the retirement email reaches a rota, not a person. These notices go to the billing or account contact, which is frequently someone who left, and a 60-day notice that sits unread for 50 days is a two-week notice.

Do the inventory first, before anything else on this page. It is an hour of work, it requires no new infrastructure, and it converts an unbounded risk into a list with dates — at which point every remaining decision is schedulable. The single most common way this goes badly is not a hard migration; it is a model ID nobody knew was in production, in a service nobody owns, discovered on the day the requests started failing.

Related: choosing a model for the evaluation you will repeat every time this happens, incident response for agents for the day it goes wrong anyway, and model families for reading a provider's lineup well enough to predict which of your models is next.