●NANOLITE — Nano Banana 2 Lite is here: Google's fastest and most cost-efficient Gemini Image model, made for running lightweight image generation cheaply●OMNIFLASH — Gemini Omni Flash is in public preview, a natively multimodal model that lets enterprises and developers build custom, dynamic video workflows●AGENTS — Managed Agents expand with background: true for async server-side runs and polling, remote MCP server integration, and refreshing credentials across interactions●MEMORY — The Memory Bank IngestEvents API is generally available, decoupling event ingestion from memory generation so you can stream content continuously●THROUGHPUT — Provisioned Throughput now lets you submit up to seven pending orders for the same model and region●DEPRECATE — Image generation models shut down on August 17, and the Grok 4.1 family on the Gemini Enterprise Agent Platform on August 20●NANOLITE — Nano Banana 2 Lite is here: Google's fastest and most cost-efficient Gemini Image model, made for running lightweight image generation cheaply●OMNIFLASH — Gemini Omni Flash is in public preview, a natively multimodal model that lets enterprises and developers build custom, dynamic video workflows●AGENTS — Managed Agents expand with background: true for async server-side runs and polling, remote MCP server integration, and refreshing credentials across interactions●MEMORY — The Memory Bank IngestEvents API is generally available, decoupling event ingestion from memory generation so you can stream content continuously●THROUGHPUT — Provisioned Throughput now lets you submit up to seven pending orders for the same model and region●DEPRECATE — Image generation models shut down on August 17, and the Grok 4.1 family on the Gemini Enterprise Agent Platform on August 20
If you're building applications with the Gemini API, you'll eventually receive a notification that your current model is being deprecated. This is a normal part of the API lifecycle—Google regularly releases improved models and phases out older ones.
When this happens, you might wonder:
Which model should I migrate to?
Will my existing code break?
How do I handle compatibility issues?
What if something goes wrong during migration?
Understanding Model Lifecycle
The Three Stages
Every Gemini API model goes through three distinct phases:
Stage 1: General Availability (GA)
The model is newly released and fully supported in production. Google provides regular updates and improvements during this phase.
Stage 2: Deprecation Period
Google announces an end-of-life date for the model. You'll receive notifications saying something like, "This model will be deprecated on June 30, 2025." Importantly, the model still works completely during this phase. You have time to plan your migration.
Stage 3: End of Life (Sunset)
After the announced date, the model becomes unavailable. Any API calls specifying that model will fail with an error. This is when migration becomes mandatory.
What to Do When You Get Notified
When you receive a deprecation notice from Google, take these three actions immediately:
Read the notification carefully — Identify which model is affected and the exact deprecation date
Check compatibility — Review the new model's documentation and identify any differences
Create a migration plan — Set a realistic timeline to migrate before the deadline
✦
Thank you for reading this far.
Continue Reading
What follows includes implementation code, benchmarks, and practical content we hope you'll find useful. This site runs without ads — server and development costs are supported entirely by members like you. If it's been helpful, we'd be truly grateful for your support.
WHAT YOU'LL LEARN
✦A dependency-audit script that mechanically catches time-bounded deprecations in CI
✦Consolidating model names into a config module so each migration touches one file
✦A decision matrix comparing email alerts, manual audits, and CI automation by outage risk
Secure payment via Stripe · Cancel anytime
✦
Unlock This Article
Get full access to the rest of this article. Buy once, read anytime. This site is ad-free — your support goes directly toward keeping it running.
You can capture these headers programmatically (covered later in "Programmatic Detection").
Step-by-Step Migration Process
Step 1: Study the New Model's Documentation
Before migrating, understand exactly how the new model differs from the old one. Check:
Supported input/output formats — Text, images, video, audio support
Token limits — Maximum input and output tokens
Context window — How much text can be processed at once
API parameters — Are temperature, top_p, and others the same?
Pricing — Cost per request and token rates
For example, migrating from gemini-1.5-pro to gemini-2.0-pro involves:
Input token limit: 1,000,000 (unchanged)
Output token limit: 8,000 → 16,000 (increased)
Video processing: Both support it (improved in v2.0)
Function calling: Both support it (expanded in v2.0)
Step 2: Test in Staging First
Never test directly in production. Use a staging environment to verify the new model works with your code:
const { GoogleGenerativeAI } = require("@google/generative-ai");const client = new GoogleGenerativeAI({ apiKey: process.env.GEMINI_API_KEY,});async function testMigration() { try { // Specify the new model const model = client.getGenerativeModel({ model: "gemini-2.0-pro", }); const response = await model.generateContent( "What is your model version?" ); console.log("Model test passed:", response.text()); // Test critical features await testFunctionCalling(model); await testMultimodalInput(model); await testResponseFormat(response); } catch (error) { console.error("Test failed:", error.message); process.exit(1); }}async function testFunctionCalling(model) { // Ensure function calling still works const response = await model.generateContent({ contents: [ { parts: [ { text: "Get the weather for Tokyo", }, ], }, ], tools: [ { functionDeclarations: [ { name: "getWeather", description: "Get weather for a city", parameters: { type: "object", properties: { city: { type: "string", description: "City name", }, }, required: ["city"], }, }, ], }, ], }); console.log("Function calling works:", !!response.functionCalls);}async function testMultimodalInput(model) { // Verify image processing const fs = require("fs"); const imageData = fs.readFileSync("test-image.jpg"); const base64 = imageData.toString("base64"); const response = await model.generateContent({ contents: [ { parts: [ { inlineData: { mimeType: "image/jpeg", data: base64, }, }, { text: "Describe what you see in this image", }, ], }, ], }); console.log("Image processing works:", response.text().length > 0);}async function testResponseFormat(response) { // Verify response structure hasn't changed console.log("Usage metadata available:", !!response.usageMetadata); console.log("Text method works:", typeof response.text === "function");}testMigration();
Key things to verify:
Basic text generation works
Multimodal inputs (images, video) are processed correctly
Function calling features work
Response format is as expected
Error handling functions properly
Step 3: Gradual Rollout Strategy
After staging tests succeed, roll out to production gradually using feature flags:
// Control which model to use via environment variableconst targetModel = process.env.USE_NEW_MODEL === "true" ? "gemini-2.0-pro" : "gemini-1.5-pro";const model = client.getGenerativeModel({ model: targetModel,});
Recommended rollout phases:
Phase 1: 5% of traffic (1-2 days)
Send 5% of requests to the new model. Monitor closely for errors and anomalies.
Phase 2: 25% of traffic (3-5 days)
If Phase 1 is stable, increase to 25%. Watch for response quality changes and latency variations.
Phase 3: 100% of traffic
Once confident, migrate all traffic to the new model.
Step 4: Clean Up Old Model References
One week before the sunset date, remove all references to the deprecated model from your codebase. Add defensive error handling in case any old code accidentally tries to use the deprecated model:
const DEPRECATED_MODELS = ["gemini-1.5-pro"];function validateModelName(modelName) { if (DEPRECATED_MODELS.includes(modelName)) { throw new Error( `Model ${modelName} has been sunset. Please use gemini-2.0-pro instead.` ); } return true;}
Common Migration Errors and Solutions
Error 1: "Model is no longer available"
Error: Model 'gemini-1.5-pro' is no longer available.
Please use 'gemini-2.0-pro' instead.
Cause: Using a model past its sunset date
Solution: Replace model names in your codebase
# Find all occurrencesgrep -r "gemini-1.5-pro" src/# Replace with new model namesed -i 's/gemini-1.5-pro/gemini-2.0-pro/g' src/**/*.js
Error 2: "Parameter not supported"
Error: Parameter 'safety_settings' is not supported
in this model.
function safeGetText(response) { // Try new format first if (response.text && typeof response.text === "function") { return response.text(); } // Try old format if (response.content && response.content[0]) { return response.content[0].parts[0].text; } // Fallback return null;}
async function checkTokenCount(prompt) { const model = client.getGenerativeModel({ model: "gemini-2.0-pro", }); const countResult = await model.countTokens(prompt); if (countResult.totalTokens > 1000000) { console.warn("Input too long. Split into smaller chunks."); return false; } return true;}
Safe Migration: Fallback Implementation
For mission-critical services, implement automatic fallback to the old model if the new one fails:
async function generateWithFallback(prompt, options = {}) { const models = ["gemini-3.1-pro", "gemini-3.5-flash"]; let lastError = null; for (const modelName of models) { try { console.log(`Trying ${modelName}...`); const model = client.getGenerativeModel({ model: modelName, }); const response = await model.generateContent({ contents: [{ parts: [{ text: prompt }] }], ...options, }); console.log(`Success with ${modelName}`); return response; } catch (error) { lastError = error; console.warn(`Failed with ${modelName}: ${error.message}`); } } throw new Error(`All models failed: ${lastError.message}`);}// Usageconst response = await generateWithFallback("Explain quantum computing");console.log(response.text());
This ensures your service keeps running even if the new model encounters issues.
Migration Best Practices
Pre-Migration Checklist
Before executing the migration, verify:
[ ] Read the new model's complete documentation
[ ] Tested in staging for at least one week
[ ] Created production backups
[ ] Prepared a rollback plan
[ ] Set up monitoring dashboards (error rate, latency)
[ ] Communicated timeline to the team
Monitoring During Migration
After switching to the new model, watch these metrics:
Error rate — Alert if it spikes by more than 5%
Response quality — Monitor for user complaints
Latency — Check if response time increased significantly
Success rate — Track consistent API success percentage
Rollback Plan
Have a quick rollback procedure ready in case the new model causes critical issues:
async function rollback() { console.log("Rolling back to old model..."); process.env.USE_NEW_MODEL = "false"; // Restart your application process.exit(0);}// Trigger this if error rate exceeds thresholdif (errorRate > 0.05) { await rollback();}
Catching Time-Bounded Deprecations Before They Bite: Automating the Dependency Audit
The deprecations that hurt most are the ones with a fixed shutdown date. Image-preview models, for instance, sometimes give only a few weeks between the announcement and removal. You do not want to discover the deadline by watching your production pipeline fail.
As an indie developer calling the Gemini API from several services, I sometimes lose track of exactly which code hard-codes which model name. So I started running a small script on a schedule that audits model names across the source tree and cross-checks them against the known sunset dates.
// audit-models.mjs — inventory model names in the repo and check them against sunset datesimport { readdir, readFile } from "node:fs/promises";import { join, extname } from "node:path";// Sunset dates (maintained by hand, or pulled from the deprecations doc)const SUNSET = { "gemini-3.1-flash-image-preview": "2026-06-25", "gemini-3-pro-image-preview": "2026-06-25",};const MODEL_RE = /gemini-[a-z0-9.\-]+/g;const SKIP = new Set(["node_modules", ".git", ".next", "dist", "build"]);async function* walk(dir) { for (const ent of await readdir(dir, { withFileTypes: true })) { if (SKIP.has(ent.name)) continue; const p = join(dir, ent.name); if (ent.isDirectory()) yield* walk(p); else if ([".js", ".mjs", ".ts", ".tsx", ".json"].includes(extname(ent.name))) yield p; }}const hits = new Map(); // model -> Set<file>for await (const file of walk(process.cwd())) { const text = await readFile(file, "utf8"); for (const m of text.matchAll(MODEL_RE)) { if (!hits.has(m[0])) hits.set(m[0], new Set()); hits.get(m[0]).add(file); }}const today = new Date();let risk = 0;for (const [model, files] of [...hits].sort()) { const sunset = SUNSET[model]; const days = sunset ? Math.ceil((new Date(sunset) - today) / 86400000) : null; const flag = days != null && days <= 30 ? `⚠️ ${days} days left (${sunset})` : ""; if (flag) risk++; console.log(`${model.padEnd(36)} ${files.size} file(s) ${flag}`);}process.exit(risk > 0 ? 1 : 0);
Because it exits with process.exit(1), wiring it into CI lets you mechanically block any pull request that still references a model due to be removed within 30 days. Manual review fails exactly when people are busiest. Letting the pipeline stop it is far more reliable.
Here is a rough comparison of three operational patterns, based on what I measured across a handful of my own indie-developer services.
Pattern
Time to notice deprecation
Emergency fixes
Production outage risk
Relying on email alerts (no audit)
Days — or never
Frequent
High
Monthly manual audit
Up to ~30 days
Occasional
Medium
Automated audit in CI (above)
Immediate, at PR time
Almost none
Low
The key is to keep model names in a single place. When they are scattered as string literals, even a good audit script leaves you many edits to make. I consolidate them into a config module and have callers reference only the key.
// config/models.mjs — always reference model names through hereexport const MODELS = { draft: "gemini-3.5-flash", // high-frequency, low-cost work like drafting and classification finalize: "gemini-3.1-pro", // work that needs stronger reasoning};
With this in place, each deprecation means editing a single file. The audit script can also read config/models.mjs to see which models are currently in use. It is a quiet bit of plumbing, but it pays off on every migration.
Summary
Migrating from a deprecated Gemini API model is straightforward when done systematically. Key takeaways:
Don't panic — You have weeks to plan
Test thoroughly — Use staging before touching production
Your migration will go smoothly if you take time to plan and test. Good luck!
Share
Thank You for Reading
Gemini Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.