Gemini 3.5 Flash: Migrating without changing behavior by accident
Here's the rule: I don't ship a Gemini 3.5 Flash migration until the new model passes the same contract tests and task evaluations the old one passed, with a rollback wired in. That's it. That's the whole policy. It reads like caution for its own sake, and the rest of this piece is me earning it, because it's the only thing standing between you and a rollback nobody planned for.
Google lists Gemini 3.5 Flash as a current stable model in the Gemini line and points new projects at the generally available Interactions API: a fast multimodal model built for high-volume, interactive, tool-assisted work. The identifier to test against is gemini-3.5-flash. Check Google's own model documentation before you wire anything up, because aliases, previews, prices, and availability all move after an article like this one goes out.
Gate the swap on evals, not vibes
Whether Gemini 3.5 Flash feels smarter in a demo doesn't matter much. What matters is which of your application's contracts the new model quietly breaks while every API call still returns success. Define success before sending it a real prompt: for extraction, a schema-valid record whose fields trace back to source text; for coding, a patch that clears tests and review; for research, a claim set with sources a human can follow. A response that merely reads well satisfies none of that.
Pin both versions and replay real traffic through them, not a curated demo set. Diff the structured outputs field by field. Inspect the tool calls, not just the final prose. Put the new model behind a route you can flip back with one config change, and leave it there until you trust it. Carry the entire request across the comparison: a model can look worse simply because one harness hands it native tool access while another pastes raw terminal output in as a string. Hold the workflow constant, and let each provider use its own message format underneath.
model id + dated API version, prompt/tool-schema revision
input tokens, cached tokens, reasoning tokens, output tokens
queue time, time-to-first-token, total completion time
outcome: pass / retry / abstain / human fix
provider errors and which fallback route fired
Same alias, different animal
The expensive mistake is editing a model string in a config file and calling the deploy done because nothing threw an exception. Frontier models make this hard to catch: almost everything they produce looks plausible on a skim, and a reviewer skimming prose stands no chance against a model that got fluent in a slightly different way. Measure what ordinary code can check. Ask a reviewer to name one concrete defect, not rate a vibe. Keep the failures. Don't delete the transcripts where the new model got it wrong; they're worth more than a folder of clean successes, because they show you where to route around it.
Long context and tool calls don't get a pass
Long context windows deserve more suspicion, not less. Read the notes on structuring long-context workflows before assuming caching alone saves you. A bigger window doesn't remove prefill time, doesn't remove retrieval noise, and does nothing to separate instructions you trust from documents you don't. If the API supports caching, put your stable prefix first and keep anything volatile, like a session id, well clear of the cache boundary, or you'll pay to recompute it every call. Don't dump an entire history in when a structured checkpoint does the same job for a fraction of the tokens. Output needs the same discipline: a short decision plus its evidence is cheaper to generate and easier to review than an essay nobody asked for.
Tool use changes what can go wrong, too. The provider might improve function selection, but your application still validates arguments, authorizes the caller, caps the blast radius of side effects, handles duplicate requests, and logs what happened. A web page, a file, a tool's return value: none of that is authority, it's data sitting next to your prompt. A more capable model doesn't replace a narrower interface. If anything, the more it can do, the more that interface matters.
Two lanes, one rule for switching between them
Keep a cheap, fast lane for the routine bulk of requests, and a specific condition for when a request earns escalation to the pricier model. The strongest model should only see requests that genuinely benefit from its capability, not every request your gateway can send it. The cheap tier stops being cheap once its retries and review burden outweigh what it saved on inference, so measure that instead of assuming it.
Treat the migration as ordinary operations work. Pin dated versions where stability matters more than freshness. Watch the vendor's deprecation notices instead of finding out the hard way. Canary a new alias on a slice of traffic before it takes over everything. Keep a known-good fallback wired and tested, not merely documented. Re-run your evaluation set whenever the model, prompt, tool contract, or reasoning default changes, because any one of those can quietly change what pass means.
None of this crowns Gemini 3.5 Flash the permanent answer. The point was never to find a winner and stop looking, it's to know which work this model does reliably, what that costs in tokens and review time, and the moment your router should hand the request to something else instead. The tradeoff I accept on purpose: this is slower than swapping a model id and shipping the same afternoon. I give up the small satisfaction of being first to use the new thing. What I get instead is not learning which contract broke from a user's bug report.