Best Model for Migrations: Consistency Over Intelligence
Framework and language migrations are hundreds of near-identical edits. The model property that decides success is consistency across files, not peak reasoning.
A migration is not one hard problem. It is four hundred instances of the same medium problem, and the thing that determines whether it succeeds is whether instance three hundred and eighty is handled the same way as instance one.
That reframing changes the model requirement completely. Peak reasoning quality barely matters. What matters is variance — how much the model's approach drifts across a long series of similar tasks — and that is a property almost nobody benchmarks.
Drift is the failure mode, not errors
Run a model over two hundred files converting a component pattern and you will not get two hundred failures. You will get one hundred and seventy correct conversions and thirty that are subtly different: a slightly different import ordering, a different choice of null handling, an extra abstraction it decided was cleaner on file ninety.
None of those thirty are wrong in isolation. Collectively they are a mess, because now your codebase has four variants of the same pattern and the next person cannot tell which is canonical.
The mitigation is to remove the model's freedom rather than hope for discipline. Write the target pattern out explicitly — a complete before-and-after example of a representative file — and include it in every single request. Do not rely on the model remembering what it did fifty files ago, because in a fresh session it did not, and in a long session attention to early instructions decays.
Decide what is a codemod and what is a model
This is the judgement call that separates a two-day migration from a three-week one.
Anything expressible as a deterministic syntax tree transformation should be a codemod. Renaming a method, changing an import path, reordering arguments, wrapping calls in something — these have exact rules, and a codemod applies them identically to every file at zero marginal cost with no review burden.
Use a model for the residue: the cases where the transformation depends on semantics rather than syntax. Converting callbacks to async requires understanding whether the callback runs synchronously. Splitting a god object requires deciding what belongs where. These have no mechanical rule, which is exactly why they are worth model tokens.
The strong play is to use a model to write the codemod, then run the codemod. You get model-level understanding of the transformation with codemod-level consistency in its application, and the review burden collapses to reviewing one script instead of four hundred diffs.
Cost is dominated by volume, not by depth
Migration economics are unusual. Each individual task is small, so you never need a long reasoning trace, but you run thousands of them, so per-call price compounds hard.
Work out the actual arithmetic before choosing. A file at roughly 3,000 input tokens and 2,000 output tokens, across 400 files, is 1.2M input and 800K output. On DeepSeek V4 Flash at around $0.14 in and $0.28 out per million, that is well under a dollar. On Kimi K3 at $3 in and $15 out, the same run is around $16.
Sixteen dollars is not a lot in absolute terms, and if K3 gets it right where Flash does not, it is obviously worth it. But migrations rarely run once — you will iterate on the prompt, discover an edge case, and re-run the whole set five or six times. Multiply accordingly. Batching requests to save money and prompt caching both apply directly, since the pattern example in your prompt is identical on every call.
Kimi K3 prices cached input at $0.30 per million against $3 uncached, a factor of ten. On a migration where the same instructions and example prefix every request, that is not a rounding error.
The pilot batch is not optional
Never start a migration by running the full set. Run twenty files, review every one by hand, and count the categories of failure.
What you learn in those twenty is worth more than any benchmark. You find out which edge cases your prompt does not cover, whether the model is inventing abstractions, and what your actual per-file success rate is. If it is 85 percent, a 400-file migration leaves sixty files needing manual repair, and you should fix the prompt before proceeding rather than discovering that at the end.
Then run in checkpointed batches of fifty, with each batch on its own branch or commit. When batch four goes wrong you revert batch four, not the whole migration. This sounds obvious and is skipped constantly.
Verification has to be mechanical
You cannot meaningfully review four hundred diffs by hand, and pretending otherwise is how migrations ship regressions.
Build the checks first. The type checker and linter catch structural failures for free. A test suite that passes before and after catches behavioural ones. For the consistency question specifically, grep for the old pattern across the codebase after each batch — any remaining instance is either a miss or an intentional exception you should document.
Where you genuinely have no tests, generate characterisation tests before the migration rather than after. Generating tests with LLMs covers making those useful, and working with legacy code covers the case where the pre-migration state is itself poorly understood.
Recommendation
For mechanical, well-specified per-file transformations at volume, DeepSeek V4 Flash. The task is easy, the volume is high, and the compiler catches structural failures — this is the price tier the work belongs in.
For the semantic residue where each case needs judgement, GLM-5.2 at high reasoning effort. It is strong on structured code work, MIT licensed if you want to run it yourself, and its two effort levels let you dial spend to difficulty.
For designing the migration — deciding the target pattern, writing the codemod, working out the tricky category of cases — spend on Kimi K3 once. That is a single expensive call whose output you reuse four hundred times, which is the best possible shape for an expensive model.
The decision rule: codemod what you can, pilot twenty files before running four hundred, checkpoint every fifty, and never let the model choose the target pattern independently on each file. Batch job model selection covers the operational side of running these at scale.
Common questions
Should I use a model or a codemod for a migration?
Both. Codemod anything expressible as a deterministic syntax transformation, and use the model for cases that depend on semantics. Best of all, have the model write the codemod so you review one script rather than four hundred diffs.
How do I stop the model handling later files differently to earlier ones?
Include a complete before-and-after example of the target pattern in every single request. Do not rely on the model remembering what it did fifty files ago, because attention to early instructions decays over a long session.
Does prompt caching help on a migration?
Considerably. Every request shares the same instructions and pattern example, which is the ideal cache shape. Kimi K3 prices cached input at $0.30 per million against $3 uncached, a tenfold difference on the shared prefix.