TL;DR.
Keeping LLM inference in one region now has a price on most rate cards. Anthropic, OpenAI and Google Vertex all charge about 10% more for it, on every token line. Most teams turn it on the way compliance asks for it: once, for the whole workspace. That pays the premium on every request, including the ones that never touch regulated data.
- The premium is about 10%, almost everywhere it has a name. Claude with
inference_geo: "us"is 1.1x on input, output, cache writes and cache reads. OpenAI's regional endpoints add 10% for models released on or after March 5, 2026. Gemini on a non-global Vertex endpoint costs 10% more. Azure's EU Data Zone is +10% on most models and +20% on GPT-6. - Where it has no name, it can be bigger. On Bedrock the same open-weight model costs 0% more in Stockholm, 33% more in Frankfurt, and Gemma 3 27B costs 57% more in London. AWS doesn't call those residency charges, but you pay them if residency is why you're in that region.
- Blanket pinning pays 10% on 100% of traffic. If 30% of your spend is regulated, pinning per request cuts the premium from $10,000 to $3,000 a month on a $100,000 bill, or $84,000 a year.
- The premium is a percent. The tier is a multiple. A pinned Haiku 5.5 request costs 1/40 of a pinned Opus 5.5 request. Which model serves a regulated request matters more than whether it's pinned.
- Below is residency.py, 56 lines: a per-request geo policy that fails closed, a check that the answer came from where you asked, and a calculator that prices blanket against per-request pinning on your own usage log.
Premiums are from Anthropic's data residency docs and two third-party pricing references compiled from provider pages in August and September 2026. The $100,000 bill and the request shapes are ours, and are illustrations, not measurements. No figure here comes from Nadir customer data. This is a cost post, not legal advice.
What in-region costs.
Data residency used to be a sales conversation: an enterprise contract, a dedicated deployment, a number nobody published. In 2026 it became a line on the rate card. Here's what the major options add over the same model on a global endpoint.
| Option | Premium | Applies to | Called residency? |
|---|---|---|---|
Anthropic API, inference_geo: "us" | +10% | Claude 4.6 and later, every token line | Yes |
| OpenAI regional processing endpoint | +10% | Models released on or after March 5, 2026 | Yes |
| Google Vertex, non-global endpoint | +10% | Gemini 3 and later, since July 1, 2026 | Yes |
| Azure OpenAI, Data Zone | +10% (GPT-6: +20%) | Most models, cache lines included | Yes |
| Mistral, regional endpoint | 1.1x list | Standard API is EU-hosted by default | Yes |
| Bedrock, Claude in EU regions | +10% (Haiku 4.5, Sonnet 5, Opus 5.5) | Varies by model and region | Mostly no |
| Bedrock, open-weight models | 0% to +57% | Varies by model and region | No |
Four details matter more than the headline number.
It applies to cache reads too. Anthropic's 1.1x covers input, output, cache writes and cache reads. On a coding agent, where most tokens are cache reads, the premium is still a flat 10% of the bill. Caching doesn't dilute it.
Claude has no EU geo on the first-party API. inference_geo takes "global" or "us", and "us" is the only workspace geo. EU-regional Claude means Bedrock or Vertex regional endpoints, priced by those platforms.
Azure is moving. Microsoft's pricing page carries a notice that pricing for EU Data Zone and non-US regional deployments increases from September 1, 2026, without saying by how much. Check the current rows before you budget.
Region choice inside Europe is a cost decision. On Bedrock, gpt-oss-120b costs the US East price in Stockholm and 33% more in Frankfurt or Milan. If your requirement is "in the EU," not "in Germany," that's a third of the bill. AWS doesn't label these gaps residency, and they aren't, but residency is often the reason a team is in that region.
Why most teams pay it on everything.
The way residency gets turned on explains the bill. A customer contract or a security review says "inference must stay in region." Someone sets the workspace default, or creates a regional project, and points every service at it. Done, compliant, and 10% more on every request.
Anthropic's own migration shows how this happens by default. Organizations that had opted out of global routing under the old setting were moved to allowed_inference_geos: ["us"] and default_inference_geo: "us", with "no code changes needed." That keeps them compliant. It also means that every request to a Claude 4.6 or later model from those workspaces bills at 1.1x, whether it's a regulated patient summary or a unit test docstring.
The same blanket shows up in two more places:
- Priority Tier burndown. Each token with
inference_geo: "us"draws 1.1 tokens from your committed Priority Tier capacity. A blanket pin shrinks a capacity commitment by about 9% without anyone deciding to. - Shared rate limits. Rate limits are shared across geos, so pinning doesn't buy separate headroom. You pay more per token for the same limit.
Usually, not all of your traffic is covered by the requirement. Residency obligations tend to attach to specific data (health records, payment data, a government customer's documents) or specific tenants (the EU customer whose contract says so). GDPR regulates transfers out of the EU rather than banning them, so whether a given request must stay in region is a question for your contracts and your counsel, not a property of the whole workload. The internal tooling, the anonymized analytics, the coding agent working on your own repo, and the customers with no residency clause often don't need it.
Pin the 30%, not the 100%.
Take a $100,000 monthly bill at global prices, and say 30% of the spend is regulated: it comes from tenants or data classes that must stay in region.
| Regulated share of spend | Blanket pin | Per-request pin | Saved per month | Saved per year |
|---|---|---|---|---|
| 10% | $10,000 | $1,000 | $9,000 | $108,000 |
| 30% | $10,000 | $3,000 | $7,000 | $84,000 |
| 50% | $10,000 | $5,000 | $5,000 | $60,000 |
| 80% | $10,000 | $8,000 | $2,000 | $24,000 |
The arithmetic is simple: per-request pinning pays the premium only on pinned spend. On Azure's GPT-6 Data Zone at +20%, every number in the table doubles.
Two things make it less simple in practice.
The classification has to be right, and wrong in the safe direction. A missed regulated request served globally is a compliance incident. An unregulated request served in region is a 10% overpayment. Those aren't symmetric, so the policy should fail closed: unknown tenant, unknown data class or a failed lookup means pinned. Saving 10% isn't worth a breach of contract.
Pinning splits sessions. Requests from one conversation should stay in one geo. We haven't seen any provider document that prompt caches are shared across geos, so assume a request that switches geo mid-session starts its cache over and pays a fresh cache write, the same penalty we measured for routers that switch models mid-session in Your Router Is Fighting Your Prompt Cache. Decide the geo per tenant and session, not per turn.
If 80% of your spend is regulated, per-request pinning saves 2% of the bill and adds a policy to maintain. Keep the blanket. This is worth doing when the regulated share is well under half.
The premium is 10%. The tier is 40x.
The bigger lever on a regulated workload isn't the pin. It's the model.
On a 4,000-token-in, 400-token-out chat request, pinning Opus 5.5 to the US adds $2.40 per 1,000 requests. Serving the same request pinned on Haiku 5.5 costs $0.66 per 1,000, $23.34 less than unpinned Opus, if Haiku can do the job.
Regulated traffic is often where teams are most conservative about models: it's the health record, the contract, the payment dispute, so it goes to the biggest model by default. Some of it needs that. A lot of it is extraction, classification and templated summaries that a small model finishes. Teams that argue for a week over a 10% residency premium often leave a 10x to 40x tier gap on the same requests.
Both decisions belong at the request level, and they compose: first where (geo, from policy), then which model (the cheapest one available in that geo that clears your quality bar). Getting the order right matters. The geo constrains the model set, never the other way round.
Tutorial: residency.py.
residency.py does three things. pick_geo() decides the geo for one request from the tenant and the text. send() makes the Claude call with that geo and refuses an answer served elsewhere, using the inference_geo field Anthropic returns in usage. premium() reads a usage log and prices blanket against per-request pinning.
"""residency.py: pin only the requests that must stay in region.
pick_geo() decides per request. send() calls Claude with that geo and checks
where inference ran. premium() reads a usage log and compares a blanket pin
against a per-request pin.
"""
import csv
import re
import sys
UPLIFT = 0.10 # +10%: Anthropic inference_geo "us", OpenAI regional, Vertex non-global
PINNED_TENANTS = {"us-gov", "us-health"} # contracts that require US-only inference
SCAN = re.compile(
r"\b\d{3}-\d{2}-\d{4}\b" # US SSN
r"|\b(?:MRN|patient id)[:# ]*\d{5,}\b" # medical record numbers
r"|\b(?:\d[ -]?){13,16}\b", # card numbers
re.I,
)
def pick_geo(tenant, text, known_tenants):
"""'us' or 'global'. Unknown tenants fail closed, the scanner only adds pins."""
if tenant not in known_tenants or tenant in PINNED_TENANTS:
return "us"
return "us" if SCAN.search(text) else "global"
def send(client, model, messages, geo):
"""One Messages call pinned to geo; refuses an answer served elsewhere."""
r = client.messages.create(model=model, max_tokens=1024,
inference_geo=geo, messages=messages)
if geo == "us" and r.usage.inference_geo != "us":
raise RuntimeError(f"asked for us, served in {r.usage.inference_geo}")
return r
def premium(path):
"""Blanket vs per-request pinning for a log of tenant, text, cost_usd rows."""
rows = list(csv.DictReader(open(path, newline="")))
known = {r["tenant"] for r in rows if r["tenant"] != "unknown"}
base = sum(float(r["cost_usd"]) for r in rows)
pinned = [r for r in rows if pick_geo(r["tenant"], r["text"], known) == "us"]
pinned_cost = sum(float(r["cost_usd"]) for r in pinned)
by_tenant = sum(float(r["cost_usd"]) for r in pinned if r["tenant"] in PINNED_TENANTS)
print(f"{len(rows):,} requests, ${base:,.2f} at global prices")
print(f" pinned by contract: {by_tenant / base:6.1%} of spend")
print(f" pinned by scanner or unknown tenant: {(pinned_cost - by_tenant) / base:6.1%}")
print(f" blanket pin: ${base * (1 + UPLIFT):,.2f} (+${base * UPLIFT:,.2f})")
print(f" per-request pin: ${base + pinned_cost * UPLIFT:,.2f} "
f"(+${pinned_cost * UPLIFT:,.2f})")
print(f" saved vs blanket: ${(base - pinned_cost) * UPLIFT:,.2f} "
f"({(base - pinned_cost) / base:.1%} of spend runs global)")
if __name__ == "__main__":
premium(sys.argv[1])
On a synthetic 20,000-request log with eight tenants, two of them under a US-only contract, it prints:
20,000 requests, $1,214.28 at global prices
pinned by contract: 20.2% of spend
pinned by scanner or unknown tenant: 11.3%
blanket pin: $1,335.71 (+$121.43)
per-request pin: $1,252.52 (+$38.24)
saved vs blanket: $83.19 (68.5% of spend runs global)
How to adapt it:
- Put the contract list first.
PINNED_TENANTSshould come from the same place your contracts are tracked, not from a regex. Tenant metadata is deterministic. The scanner is a backstop. - Let the scanner only add pins. The card-number pattern above will match some order numbers and phone numbers. That's fine: a false match costs 10% on one request. Never let a scanner remove a pin that tenant policy set.
- Keep the check in `send()`. Anthropic returns where inference actually ran in
usage.inference_geo. Log it on every request, and alert on any pinned request that comes back different. That log is also the evidence your compliance team will ask for. - Set `allowed_inference_geos` anyway. For a workspace that should only ever serve regulated tenants, restrict it to
["us"]in the Console so a missing parameter can't leak a request. Run per-request pinning from a separate workspace that allows both. - Map other providers the same way. OpenAI's residency is per project with its own regional endpoint, and Bedrock and Vertex pick the region by endpoint or inference profile. The policy is the same,
pick_geo()returns a region, and the client for that region does the rest.
Where Nadir fits.
residency.py decides where. Nadir decides which model, per request, within the set you allow.
Run the router in your region. The hosted Nadir service stores data in the United States, and we don't currently offer other regions on it. For residency workloads, Nadir runs as one container inside your own VPC, in whatever region you choose, with no calls home. Point it at models in your own Bedrock account and the calls stay inside your AWS boundary, or register self-hosted open weights served with vLLM, TGI or Ollama as tiers. With store_prompts=false, logs keep a SHA-256 hash instead of the prompt text.
Route within the allowed set. Give the in-region deployment a ladder of in-region models only, and model="auto" sends each request to the cheapest of them that clears your quality floor. That's the 40x lever from the chart above, applied after the geo decision rather than instead of it. The model that served each request and its cost come back on the response, so the per-tenant split in the tutorial exists for every request without a separate export.
If you'd rather measure before anything changes, Observe mode serves exactly the model you asked for and records what routing would have chosen. With your own provider keys, Nadir charges no fee on any plan, and the provider bills you directly. Savings depend on your workload, and nothing in this post forecasts yours.
Start with a free key, or run residency.py on a week of your usage log first and see how much of your premium is buying compliance.
Conclusion.
Data residency now has a list price: about 10% on Claude, OpenAI, Gemini and most of Azure, on every token line, and anywhere from 0% to 57% on Bedrock depending on which region you pick. Most teams pay it on all their traffic because they enabled it for the whole workspace. Pin per request when the regulated share is well under half, fail closed when you're unsure, verify where each answer was served, and choose the region inside your requirement by price. Then spend the effort where the bigger number is: the model tier serving those requests.
Anthropic figures are from its data residency documentation, including the 1.1x multiplier on all token categories, the legacy opt-out migration, Priority Tier burndown and shared rate limits. OpenAI, Vertex, Azure, Mistral and Bedrock premiums are from two third-party references compiled from provider pricing pages: Digital Applied (rates retrieved August 25, 2026) and Aliteq (verified September 27, 2026). They disagree in places, and regional prices change often, so check the provider pages before you rely on any figure here. The $100,000 bill, the chat request shape and the synthetic usage log are ours, and are illustrations, not measurements. Claude prices are October 27, 2026 list prices, with Haiku 5.5 at its rate for prompts up to 100K tokens. Nothing here is legal advice. Sources: [Anthropic, Data residency](https://platform.claude.com/docs/en/manage-claude/data-residency). [Anthropic, Pricing](https://www.anthropic.com/pricing). [Digital Applied, "What Data Residency Actually Costs: A Pricing Reference," August 25, 2026](https://www.digitalapplied.com/blog/ai-data-residency-cost-premiums-reference). [Aliteq, "EU Data Residency for AI APIs: What OpenAI, Azure, Bedrock, Vertex, Mistral and Claude Charge in 2026," September 27, 2026](https://aliteq.com/eu-data-residency-ai-api-cost-2026). [OpenAI, API pricing](https://openai.com/api/pricing/). [Microsoft, Azure OpenAI pricing](https://azure.microsoft.com/en-us/pricing/details/cognitive-services/openai-service/). [Google Cloud, Vertex AI pricing](https://cloud.google.com/vertex-ai/generative-ai/pricing). [AWS, Amazon Bedrock pricing](https://aws.amazon.com/bedrock/pricing/).