GEMINI LABJP
PRO35 — July 17, the date reports had pointed to, has passed without an official Gemini 3.5 Pro announcement or model card. July 24 is being cited as the fallbackNB2LITE — Nano Banana 2 Lite, otherwise known as Gemini 3.1 Flash-Lite Image, arrives as the fastest of the family: roughly four seconds per image at $0.034 per thousandOMNI — Gemini Omni Flash enters public preview, generating video up to ten seconds long at $0.10 per second of outputEDIT — Omni Flash is built around conversational editing. Swap a character, relight a scene, or change the angle in plain language, and the original audio and video tracks stay intactSYNTHID — Both new models carry SynthID watermarking, so anything they produce can be checked for provenance from inside the Gemini appSHUTDOWN — The older image generation models are deprecated and switch off on August 17. Worth checking your migration windowPRO35 — July 17, the date reports had pointed to, has passed without an official Gemini 3.5 Pro announcement or model card. July 24 is being cited as the fallbackNB2LITE — Nano Banana 2 Lite, otherwise known as Gemini 3.1 Flash-Lite Image, arrives as the fastest of the family: roughly four seconds per image at $0.034 per thousandOMNI — Gemini Omni Flash enters public preview, generating video up to ten seconds long at $0.10 per second of outputEDIT — Omni Flash is built around conversational editing. Swap a character, relight a scene, or change the angle in plain language, and the original audio and video tracks stay intactSYNTHID — Both new models carry SynthID watermarking, so anything they produce can be checked for provenance from inside the Gemini appSHUTDOWN — The older image generation models are deprecated and switch off on August 17. Worth checking your migration window
Articles/Advanced
Advanced/2026-07-06Advanced

Being Able to Say Later Where a User's Data Was Processed — Region-Pinned Gemini (Vertex AI) Clients and a Residency Policy Gate

The default global endpoint is convenient, but it leaves you unable to explain where an EU user's data was processed. Here is a design built from three parts—a region-pinned Vertex AI client, a policy gate that forbids implicit global fallback, and a call ledger—with working code and measured latency.

gemini-advanced5vertex-ai8data-residencyproduction140python104compliance2

Premium Article

"Where does this app process text from EU users?" When someone asked me that about one of my apps, I could not answer on the spot. In code I was using the default google-genai client with no region specified, and the default global endpoint can route requests almost anywhere internally. It is fast and easy, but not being able to point to a single line that says where processing happened is a weak position to operate from. As an indie developer running several apps on AdMob revenue, some of which reach users abroad, "I cannot say where it was processed" was never someone else's problem.

Data residency looks like a large-company concern to many solo developers. But the moment you have even one EU user, it becomes your problem too. The awkward part is that it is the kind of gap you only notice after something goes wrong. Everything works fine day to day, and the absence of records first surfaces during an inquiry or a review. Here, assuming you use Gemini through Vertex AI, I will share a design that pins the region, forbids implicit fallback, and keeps calls in a form you can explain afterward—together with working code.

Why "global by default" catches up with you later

The global endpoint is excellent for availability. If one region is busy, it routes you somewhere with headroom. From a residency point of view, though, that same "route anywhere" property becomes a gap in accountability. The place where processing happened can change on every request, and if you never recorded it, you cannot later claim it stayed inside the EU.

When I logged a few days of traffic on global, the round-trip distribution for the same EU-facing calls was bimodal. Some requests clearly went somewhere near, others somewhere far, and the two were mixed together. In other words, global is not "fast"—it is "fast when it happens to land nearby," and I could not even distinguish which case I had gotten locally.

The first thing to internalize is that residency is not a latency problem but an evidence problem. Speed is a side effect; the core question is whether you can describe, in your own words and after the fact, where processing took place.

Classify your data first (do not pin everything)

If you pin every request to a region right away, you take a hit on both model availability and latency. The first move is to split the data you handle into classes. I settled on three.

ClassExamplesProcessing requirement
residencyBody text, reviews, inquiries typed by EU usersProcess inside a named region. global not allowed
regional-prefEU-facing but non-sensitive summaries and classificationsPrefer the named region; if unavailable, an allowed region
global-okFormatting public info, my own draftsAnywhere is fine (favor speed)

The starting point is to pass this class explicitly at the call site. Rather than having a human reason about "which kind of data is this?" every time, you tag it once at the entry point and let the code pick the region mechanically. The goal is to confine the decision to a single place.

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
Record, per request, which regional endpoint actually processed the data, so you can later explain your data flow to a user or a reviewer
Take home a fail-closed policy gate that forbids residency-tagged data from silently falling back to the global endpoint
Decide how much region pinning costs you in latency and model availability, backed by measured p50/p95 numbers from 500 calls each on europe-west4 and global
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

Advanced2026-07-09
Setting a Token Budget Per Free User: Balancing AdMob Revenue Against AI Feature Cost
Rate limits protect requests per minute. They do nothing for the invoice that arrives at the end of the month. Here is how I derive a per-user token budget from ad revenue, keep the ledger inside a single call wrapper, degrade gracefully at a soft cap, and detect abuse with one concentration ratio.
Advanced2026-06-21
When Gemini's Maps Grounding Quietly Fails in Production — Field Notes on Attribution, Billing Boundaries, and Fallbacks
An operations-focused look at the pitfalls that surface after you ship Grounding with Google Maps on Gemini: detecting silent grounding misses, meeting the attribution requirement, knowing which responses are billed, and building fallbacks for latency and staleness.
Advanced2026-05-05
Gemini 2.5 Pro in Production: The Pitfalls Nobody Talks About
A practical guide to the production-specific problems with Gemini 2.5 Pro—rate limit architecture, Thinking mode cost control, long-context quality management, and response quality diagnostics—with complete code examples.
📚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 →