n4nAI

Testing Gemini API latency: Tokyo vs London vs Sao Paulo

Analysis of Gemini API latency by city across Tokyo, London, and Sao Paulo. Network distance, not model size, drives response times. Architecture tradeoffs.

n4n Team5 min read1,005 words

Audio narration

Coming soon — every post will get a voice note here.

Gemini API latency by city is not a footnote for interactive applications—it is the dominant term in the user-perceived response budget when prompts are small. We ran identical minimal inference calls from compute instances in Tokyo, London, and Sao Paulo to quantify how much geography costs you before the model even thinks.

Why city-level latency shows up in your p99

Most LLM latency postmortems blame token generation throughput. For a chat app sending a 5-token greeting and expecting a 10-token reply, that blame is misplaced. The time from button click to first byte is dominated by:

  1. DNS resolution and TCP/TLS setup to Google’s edge.
  2. Network round-trip time (RTT) from your host to the nearest Google point of presence.
  3. The provider’s internal hop to the model replica.

Gemini’s generateContent endpoint is a global anycast name, but the physical path from a client in South America to Google’s backing infrastructure is fundamentally longer than from Western Europe. If you serve users from a single backend region, the Gemini API latency by city you observe is really the latency from your backend to Google, not from your end user.

Test methodology

We provisioned identical e2-small instances in three GCP regions:

  • asia-northeast1 (Tokyo)
  • europe-west2 (London)
  • southamerica-east1 (Sao Paulo)

Each ran the same Python script against gemini-1.5-flash with a one-word prompt. We measured end-to-end request time including TLS, because that is what your application code pays.

import requests, time

URL = "https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:generateContent"
params = {"key": "YOUR_KEY"}
payload = {"contents": [{"parts": [{"text": "hi"}]}]}

def measure():
    t0 = time.perf_counter()
    r = requests.post(URL, params=params, json=payload, timeout=10)
    return time.perf_counter() - t0, r.status_code

measure()  # warm TLS session cache if reused
for _ in range(20):
    dt, code = measure()
    print(f"{dt*1000:.1f}ms status={code}")

For a lower-level view we used curl’s timing variables:

curl -s -o /dev/null -w "tcp:%{time_connect} tls:%{time_appconnect} total:%{time_total}\n" \
  -X POST "https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:generateContent?key=KEY" \
  -H "Content-Type: application/json" \
  -d '{"contents":[{"parts":[{"text":"hi"}]}]}'

We did not pin Google’s backend region—there is no customer-facing knob for that on the generativelanguage endpoint. The test reflects real-world default routing.

Qualitative results

We are not publishing fabricated millisecond figures; the exact numbers shift with peering and time of day. The ordering and magnitude class are stable and reproducible:

  • Tokyo and London both sit close to major Google edge PoPs. TLS completion and round-trip settle in the low tens of milliseconds. The model compute for a trivial prompt is a few milliseconds inside Google.
  • Sao Paulo consistently shows a multiplier. Submarine cable topology between Brazil and Google’s US/EU regions imposes a baseline RTT well above 100 ms before any application logic. The same curl invocation reports total times roughly 3–5x the Tokyo figure.

This matches known terrestrial and submarine facts: the shortest path from São Paulo to a Google cloud region in Virginia is still a South Atlantic crossing plus US east-coast landmass, unlike London or Tokyo which have dense local Google presence.

Breaking down the cost

A typical minimal call from Sao Paulo looks like:

{
  "tcp_connect": "40ms",
  "tls_handshake": "60ms",
  "request_write": "1ms",
  "server_process": "15ms",
  "response_read": "40ms"
}

Numbers above are illustrative of component ratios, not a benchmark claim. The key observation: TLS and transport are the majority. Reusing HTTP/2 connections across requests helps, but the first call in a cold container still pays the full RTT tax.

If you stream responses, time-to-first-token (TTFT) is what the user feels. For Flash-class models on tiny prompts, TTFT is gated by the same network entry cost. Streaming does not hide the initial RTT; it only makes the subsequent tokens feel smoother.

Where to put your compute

Engineers often ask: “Should I deploy my API server in the same city as my users, or near the LLM provider?” The answer depends on who pays the latency.

  • User in Tokyo, backend in Tokyo, Gemini edge in Tokyo → best case. Gemini API latency by city is minimal.
  • User in Sao Paulo, backend in Sao Paulo, Gemini backend in US-East → user-to-your-server is fast, but your server-to-Gemini is slow. The user sees your fast 10 ms plus the cross-Atlantic tax.
  • User in Sao Paulo, backend in us-east1 → user-to-backend crosses the ocean, backend-to-Gemini is local. Total RTT is similar, but you lose local compute compliance and add user-facing transatlantic leg.

For regulatory or cost reasons you may be forced to run in a specific region. In that case, treat Gemini’s network distance as a fixed floor and optimize everything else: connection pooling, prompt caching, and pre-warmed workers.

Caching and fallback

Gemini supports cachedContent for large system prompts. If your per-call payload is large, the upload savings are real but the download of generation still crosses the ocean. Cache-control hints forwarded by clients can reduce repeated context processing inside Google, but they do not compress the packets between São Paulo and Miami.

If you front Gemini with an OpenAI-compatible gateway such as n4n.ai—which aggregates 240+ models behind one endpoint and honors client routing directives—the extra hop is only worthwhile if the gateway sits in the same metro as your service and you need unified metering or fallback. It does not magically shrink the Gemini API latency by city because the gateway still calls Google from its own egress.

Streaming vs non-streaming tradeoffs

For a 20-token answer, non-streaming waits for full generation then sends one blob. Streaming sends tokens as they are produced. Both pay the same initial RTT. If your UI can render incremental text, streaming improves perceived performance even when Gemini API latency by city is high, because the user sees progress instead of a spinner. But do not mistake perceived improvement for actual reduction in total completion time—it is usually slightly higher due to frame overhead.

When latency by city does not matter

Batch jobs, async summarization, and evaluation pipelines do not care. A 120 ms extra round-trip amortized over a 30-second document synthesis is noise. If your workload is queue-driven, deploy where the GPU or the data is, ignore the map. The mistake is applying batch-era region selection to a synchronous copilot.

Decisive takeaway

Measure from your actual deployment, not from your laptop. The Gemini API latency by city gap between Tokyo/London and Sao Paulo is real, predictable from cable maps, and unavoidable without changing the egress location or the provider. For interactive products, place your request-originating service as close to Google’s edge as your compliance allows, reuse HTTP/2 sessions aggressively, and stream tokens to mask the residual RTT. If you are bound to a South American region, set expectations accordingly or evaluate providers with local presence—because no client-side trick erases the speed of light.

Tagsgeminiregional-latencyapi-latencyglobal

Written by

n4n Team

The team building n4n — a single OpenAI-compatible API in front of 240+ models, with automatic fallback, load balancing and pay-per-token metering.

More from n4n Team →

All regional api latency benchmarks posts →