◉GEMINI LABJP
●CLI 0.62.0 — Gemini CLI v0.62.0 (Sep 29) adds Gemini 3.8 Flash and 3.5 Flash-Lite support, along with a fix that keeps the OAuth refresh token●10/02 — gemini-2.5-flash-image reaches its shutdown date today. The place to move is gemini-3.1-flash-image, and sweeping for leftover references is this week's job●TOOLS — An issue reports that Gemini CLI returns a 400 once MCP tools exceed 128. How you trim the tool count is the real question●NEW — The Gemini features that landed in Docs, Sheets, Slides and Drive in March: what I kept and what I dropped six months later●CLAUDE — Handing Claude Code's Japanese-text work to Gemini 3.8 is a pairing getting read on Zenn. The real question is which jobs to hand over and which to keep●12/31 — 90 days left until the introductory pricing ends for 3.8 / 3.7 / 3.6 Flash and robotics-er-2. 3.5 Flash stays as is●CLI 0.62.0 — Gemini CLI v0.62.0 (Sep 29) adds Gemini 3.8 Flash and 3.5 Flash-Lite support, along with a fix that keeps the OAuth refresh token●10/02 — gemini-2.5-flash-image reaches its shutdown date today. The place to move is gemini-3.1-flash-image, and sweeping for leftover references is this week's job●TOOLS — An issue reports that Gemini CLI returns a 400 once MCP tools exceed 128. How you trim the tool count is the real question●NEW — The Gemini features that landed in Docs, Sheets, Slides and Drive in March: what I kept and what I dropped six months later●CLAUDE — Handing Claude Code's Japanese-text work to Gemini 3.8 is a pairing getting read on Zenn. The real question is which jobs to hand over and which to keep●12/31 — 90 days left until the introductory pricing ends for 3.8 / 3.7 / 3.6 Flash and robotics-er-2. 3.5 Flash stays as is
Articles/Updates
◎ Updates/2026-07-04Intermediate

Before the August 17 Gemini Image Model Shutdown: Inventory Where You Actually Call Them First

Some Gemini image generation models retire on August 17. Before choosing a replacement, here is how to inventory which models are actually being called, and from where, using your request logs.

Gemini API244image generation5model migration5deprecation8operations19

When I saw the notice that some image generation models would retire on August 17, the first thing I did was not to pick a replacement. What made me stop was a simpler, more uncomfortable fact: I couldn't say for certain which of my own scripts were calling which model, or when.

I run a few pipelines that generate images for wallpaper apps as an indie developer, and model IDs end up scattered in more places than you'd expect — a validation script from months ago, a batch that only runs at month-end, a string buried in a config file. Even if I settle on one GA model to migrate to, missing a single call site means the thing that breaks on the morning of August 17 is the one job I never noticed. So before migrating, I did an inventory. Here's the process.

Why grep alone misses call sites — three blind spots

The obvious first move is to search the whole repository for the model name. That's useful, but incomplete. Relying on static string search alone leaves three gaps.

First, model IDs loaded from environment variables, config files, or a database. The code only says os.environ["IMAGE_MODEL"], and the actual value lives only in the deployment environment. Second, IDs passed in as arguments. If you've built a wrapper around the API, the model name may come from the caller, and static analysis can't tell you which value actually arrives. Third, old jobs you assume are already dead. A schedule you thought you disabled quietly still running is the scariest pattern in any deprecation.

In short, static code search tells you where a model might be called, but not whether it's actually being called right now. Collecting those two things separately is the point of this article.

Aggregate the models that are actually being called from your logs

Request logs fill the gap that grep leaves. If you record the model ID and a timestamp on every API call, you can mechanically compute which models were called, how recently, and how often. Even if you don't log yet, if your calls pass through a single wrapper, one added line starts the record today.

Here's a minimal wrapper that records each call before running it.

import json, time, pathlib
 
LOG_PATH = pathlib.Path("logs/model_calls.jsonl")
LOG_PATH.parent.mkdir(parents=True, exist_ok=True)
 
def call_image_model(client, model_id: str, prompt: str, *, caller: str):
    """Wrapper for image generation. Records model_id and caller before running."""
    record = {
        "ts": time.time(),
        "model": model_id,
        "caller": caller,  # e.g. an identifier for the call site: "wallpaper_batch.generate"
    }
    with LOG_PATH.open("a", encoding="utf-8") as f:
        f.write(json.dumps(record, ensure_ascii=False) + "\n")
 
    return client.models.generate_images(model=model_id, prompt=prompt)

Always passing caller is the key. Later you can trace not just "which model is used most" but "which process is calling that model," all in one pass.

Then aggregate the accumulated logs. Group the retiring model IDs and report each one's call count, last-called date, and callers.

import json, pathlib
from collections import defaultdict
from datetime import datetime, timezone
 
# List the model IDs retiring on August 17 (check the official deprecation list and update).
RETIRING = {
    "gemini-3.1-flash-image-preview",
    "gemini-3-pro-image-preview",
}
 
stats = defaultdict(lambda: {"count": 0, "last_ts": 0.0, "callers": set()})
 
for line in pathlib.Path("logs/model_calls.jsonl").read_text(encoding="utf-8").splitlines():
    rec = json.loads(line)
    if rec["model"] not in RETIRING:
        continue
    s = stats[rec["model"]]
    s["count"] += 1
    s["last_ts"] = max(s["last_ts"], rec["ts"])
    s["callers"].add(rec.get("caller", "unknown"))
 
for model, s in sorted(stats.items(), key=lambda kv: kv[1]["count"], reverse=True):
    last = datetime.fromtimestamp(s["last_ts"], tz=timezone.utc).strftime("%Y-%m-%d")
    callers = ", ".join(sorted(s["callers"]))
    print(f"{model}: {s['count']} calls / last {last} / callers: {callers}")

Run this and, for each retiring model, you see at a glance whether it's still alive, how frequently, and who calls it. A count of zero means the migration is less urgent even if the code still exists. Conversely, a caller you overlooked in grep may show up here by name for the first time. In my case, a validation batch I thought I'd disabled surfaced with a last call three days prior — a quiet moment of dread.

Assign a migration priority to each call site you found

Once the inventory is in, don't try to migrate everything at once — assign priorities. The three inputs are call volume, recency, and whether it runs unattended. Unattended jobs especially deserve a higher priority even at low volume, because when they stop, no one notices right away.

Nature of the call siteMigration priorityReason
Unattended scheduled batch, called recentlyHighestA stoppage goes unnoticed and its impact spreads quietly
User-triggered with high call volumeHighA shutdown directly degrades the experience
Manually run validation or experiment scriptsMediumLittle real harm if it stops, but neglect breeds confusion later
Zero calls in the logsLow (but consider deleting)Effectively unused — a good chance to remove it from the code

Replace the highest-priority sites with your chosen GA model first, then run the same log aggregation again. If calls to the retiring models no longer appear in the newer records, that path's migration is done. Not skipping this "confirm in the logs after switching" step is, I've found, the surest way to pass August 17 quietly.

For choosing the replacement model and the code diffs to verify during the switch, I've written up Gemini's image generation preview models retire on June 25 — the code diffs and verification steps for moving to GA. For the pipeline-side preparation that keeps the morning of a shutdown calm, What I learned on the morning a preview image model stopped — Gemini image model GA migration and a deprecation-resilient pipeline is a useful companion.

Keep model IDs in one place

The biggest lesson from this inventory was that the more model IDs are written directly throughout the code, the more searching each deprecation forces on you. To prepare for the next one, consolidate model IDs into a constants module or configuration and have call sites reference them by name — so next time, one change is enough. The thinking behind pinning model IDs and detecting changes, including the accident of a default model silently moving up, is explored in Don't let "the default model just went up" become an incident in the Gemini API — pinning model IDs and detecting default changes.

As a concrete first step you can take today, add one line of caller-tagged logging to your image generation calls. By August 17, where your code truly needs migration will be visible as data, not guesswork. Thank you for reading.

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.

  • ✦Copy-paste ready implementation code
  • ✦New advanced guides published daily
  • ✦$5/mo or $15 for lifetime access
View Membership →

If you found this article helpful, a small tip ($1.50) would mean a lot to us. Your support helps keep this site ad-free and covers server and hosting costs.

Related Articles

◎ Updates2026-09-26
Swapping a Preview TTS Model for 3.8 Flash-Lite TTS, Then Re-choosing a Voice From 150+ Candidates
On September 22, gemini-3.8-flash-lite-tts went GA as the replacement for the 3.1 Flash TTS preview. Here is what I did over one week: replacing the preview model name behind my healing app's guidance audio and re-choosing a voice from the new /v1beta/voices endpoint.
◈ API / SDK2026-09-12
gemini-2.5-flash-image stops on October 2, and the replacement the table names retired in June
gemini-2.5-flash-image shuts down on October 2, 2026, but the recommended replacement listed in the official table, gemini-3.1-flash-image-preview, was already retired on June 25. Here is the script I wrote to follow replacement chains to their end, and what it found across every row of the table.
⟐ Dev Tools2026-08-17
Your Shipped App Still Remembers the Retired Model
Finishing the server-side migration is only half of a model retirement. The older builds of your app still hold the old model name, and once the cutoff passes, rolling back stops being a recovery option. Here is how I moved model resolution onto the server.
📚RECOMMENDED BOOKS
Build a Large Language Model (From Scratch)
Sebastian Raschka
LLM Dev
Prompt Engineering for LLMs
Berryman & Ziegler
Prompting
AI Engineering
Chip Huyen
AI Eng
* Contains affiliate links