GEMINI LABJP
NANOLITE — Nano Banana 2 Lite is here: Google's fastest and most cost-efficient Gemini Image model, made for running lightweight image generation cheaplyOMNIFLASH — Gemini Omni Flash is in public preview, a natively multimodal model that lets enterprises and developers build custom, dynamic video workflowsAGENTS — Managed Agents expand with background: true for async server-side runs and polling, remote MCP server integration, and refreshing credentials across interactionsMEMORY — The Memory Bank IngestEvents API is generally available, decoupling event ingestion from memory generation so you can stream content continuouslyTHROUGHPUT — Provisioned Throughput now lets you submit up to seven pending orders for the same model and regionDEPRECATE — Image generation models shut down on August 17, and the Grok 4.1 family on the Gemini Enterprise Agent Platform on August 20NANOLITE — Nano Banana 2 Lite is here: Google's fastest and most cost-efficient Gemini Image model, made for running lightweight image generation cheaplyOMNIFLASH — Gemini Omni Flash is in public preview, a natively multimodal model that lets enterprises and developers build custom, dynamic video workflowsAGENTS — Managed Agents expand with background: true for async server-side runs and polling, remote MCP server integration, and refreshing credentials across interactionsMEMORY — The Memory Bank IngestEvents API is generally available, decoupling event ingestion from memory generation so you can stream content continuouslyTHROUGHPUT — Provisioned Throughput now lets you submit up to seven pending orders for the same model and regionDEPRECATE — Image generation models shut down on August 17, and the Grok 4.1 family on the Gemini Enterprise Agent Platform on August 20
Articles/API / SDK
API / SDK/2026-07-18Advanced

The Same gemini-flash-latest Pointed to Different Models in Different Regions

Alias resolution rolls out region by region. Send the same gemini-flash-latest to Tokyo and us-central1 and, for a few days, different models answer. Here is why that quietly invalidates your comparisons, and how a one-shot probe catches it.

gemini-api277vertex-ai8model-versioningmulti-regionproduction140

Premium Article

Same prompt. Same code. Same SDK version. The only difference was the region — and yet asia-northeast1 and us-central1 were returning noticeably different response lengths.

This was right after July 15, when gemini-flash-latest began resolving to Gemini 3.5 Flash. My setup was the kind of thing an indie developer ends up with: Tokyo for users in Japan, us-central1 for everyone else, the same alias string written in both paths because writing it twice felt like duplication. For a few days, those two strings meant two different models.

The awkward part was that nothing broke. Both responses were valid. The JSON parsed. All that happened is that a week of notes — "Tokyo feels faster," "the English output runs shorter" — turned out to measure something other than what I thought. I had been measuring model differences and calling them regional differences.

An alias is not a global name

I had quietly assumed gemini-flash-latest was a global shortcut: one name, one underlying model, no matter where you call it from. That is not what it is. An alias is a local name for whatever the current recommended version happens to be in that region.

When a new version reaches GA, the rollout advances region by region. Not everywhere at once. So an alias does not give you these three things simultaneously:

What I assumedWhat is actually true
Same model whenever I callSwaps without notice during rollout
Same model wherever I call fromResolution skews per region for a window
I get told when it changesInvisible unless you read the response

The first row is fairly well known. The second is the one I had never accounted for — and pinning, the usual advice, only addresses the first. Anywhere I had left an alias in place across multiple regions, pinning was doing nothing for me.

The good news: the response tells you which model actually answered. That field is model_version.

# What this solves: find out which concrete version answers an alias in each
# region. While these disagree, any cross-region number you collect is
# contaminated by a model difference rather than a regional one.
import os
from google import genai
 
def resolve(location: str, alias: str = "gemini-flash-latest") -> str:
    client = genai.Client(
        vertexai=True,
        project=os.environ["GOOGLE_CLOUD_PROJECT"],
        location=location,
    )
    res = client.models.generate_content(
        model=alias,
        contents="ok",  # we only want the resolution, so keep input minimal
    )
    return res.model_version
 
for loc in ("asia-northeast1", "us-central1"):
    print(f"{loc:16s} -> {resolve(loc)}")

Sample output:

asia-northeast1  -> gemini-3.5-flash
us-central1      -> gemini-3.1-flash

Those two lines were enough to make me close that week's measurement notes. The "ok" payload is deliberate — the resolution is all I need, so there is no reason to spend input tokens. At a few tokens per call and $1.50 per million input tokens for gemini-3.5-flash, running this across two regions daily costs effectively nothing.

Skew corrupts more than your comparisons

Working through what actually breaks during the skew window, the damage fell into three directions.

Comparisons and canaries. Any design that diffs region A against region B silently assumes both are the same model. Once that assumption fails, you cannot attribute the difference to anything.

Latency numbers. "Tokyo's p95 is 200ms faster" reads like a network-distance story. If two model generations are mixed in, it might be inference time instead.

Caching. This one hurt most quietly. My response cache keyed on alias + hash(prompt). So output generated by gemini-3.5-flash in Tokyo got stored under the name gemini-flash-latest, and a us-central1 request read it back. If you share a cache across regions, you end up serving one model's output as another model's output.

The fix was a single line: key on what answered, not on what you asked for.

# What this solves: put the concrete version that answered into the cache key
# instead of the alias name, so two different models can never share a key
# during a rollout.
import hashlib
 
def cache_key(model_version: str, prompt: str) -> str:
    # model_version comes from res.model_version (e.g. "gemini-3.5-flash").
    # Keying on the alias ("gemini-flash-latest") means that the moment
    # resolution moves, stale output is served under the new model's name.
    digest = hashlib.sha256(prompt.encode("utf-8")).hexdigest()[:32]
    return f"{model_version}:{digest}"

On write you obviously have model_version in hand; on read you have not called yet, so you do not. I resolved that by having the read path reuse the region's resolution once per day. Less precise than I would like, but keeping two models out of one key mattered more than elegance.

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
Why alias resolution skews per region during a rollout, and why every cross-region measurement taken in that window is unusable
A dependency-free skew probe that sends one tiny request per region and compares the returned model_version
A freeze flag that suppresses comparisons while skew is live, plus the cache-key change that stops one model's output from being served as another's
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.

or
Unlock all articles with Membership →
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 $10 for lifetime access
View Membership →

Related Articles

API / SDK2026-04-28
Beyond Embeddings: Production Reranking with Vertex AI Ranking and Gemini-as-Judge
When pure embedding search nails the top-3 but buries the right answer at rank 4, you need a reranker. This guide walks through a production-grade two-stage architecture using Vertex AI Ranking API and Gemini-as-judge — with cost, latency, and evaluation patterns that hold up under load.
API / SDK2026-07-15
Sample what you already accepted — an audit budget that catches silent quality drift
A confidence gate only ever looks at output the model hesitated on. Silent drift sinks into the batch that sailed through. Working from a fixed 30-minutes-a-day review budget, this walks through deriving detection time from the binomial, reallocating the same budget across risk strata, and catching slow decay with a cumulative monitor.
API / SDK2026-07-06
Measure a Managed Agent's Behavior Against Fixed Scenarios Before It Reaches Production
The public-preview Managed Agents run autonomously inside an isolated sandbox, so a small prompt or config change can quietly shift their behavior. Diffing the output once, the way you would for a single prompt, is not enough. Here is how to build a regression harness that runs fixed scenarios repeatedly and judges on pass rate, plus a shadow to canary to full promotion with automatic rollback, all with runnable Python.
📚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
See all →