Regions & edge
Status: 🟩 COMPLETE Last updated: 2026-06-19 Plain-English tagline: Where your code actually runs on the physical planet — and why “the edge” (everywhere) and “a region” (one specific place) are two different deployment shapes with different trade-offs.
In plain English
Your code has to run on some physical computer in some physical place. The internet is fast but not magic — a round trip from Sydney to Virginia takes ~200ms minimum (the speed of light). For an app whose users span the globe, where you put your code determines how fast it feels.
Two distinct concepts:
-
A “region” = one specific data center in one specific city. Examples:
us-east-1(Virginia),syd1(Sydney),fra1(Frankfurt). When you deploy to a region, your code runs THERE, period. Requests from far away take longer. -
“The edge” = a fleet of small compute nodes spread across hundreds of cities globally. When you deploy to the edge, your code runs in EVERY location simultaneously. The user’s request is handled by the nearest one — typically under 50ms away anywhere on Earth.
Two completely different shapes of compute. Different things they’re good at. Different limitations.
The decision matters because:
- The database lives in a region. You can’t put a Postgres database “everywhere.”
- The compute that talks to the database can live in a region (close to the database, slow for distant users) or at the edge (close to every user, slow to reach the database).
- The faster of those two paths is what determines user experience.
Choosing well means co-locating the slowest part of your stack and routing the rest accordingly.
Why it matters
Three concrete things region/edge choices affect:
-
Latency. A poorly-placed function adds 200–600ms to every request. Multiply by the half-dozen serial round-trips in a typical page load, and a fast app becomes slow.
-
Cost. Cross-region data transfer is one of the most expensive things in cloud computing. A misconfigured stack that bounces data between continents per request racks up egress fees fast.
-
Compliance. Some regulations (GDPR, Australian Privacy Act, healthcare laws) require certain data to never leave specific countries. Your region choice can be a legal obligation, not just a performance one.
The Bible Quest project, for example, pins Vercel functions to syd1 (Sydney) because the Supabase database is in Sydney. If functions ran in iad1 (Virginia) by default, every database call would cross the Pacific — adding ~300ms × 5+ round-trips per page = 1.5+ seconds of unnecessary lag.
How regions actually work
Cloud providers have hundreds of physical data centers around the world. They group them into regions (geographic clusters, often containing multiple availability zones for fault tolerance):
| Region code | Location |
|---|---|
iad1 | Washington, DC (US East) |
sfo1 | San Francisco (US West) |
lhr1 | London |
fra1 | Frankfurt |
syd1 | Sydney |
nrt1 | Tokyo |
sin1 | Singapore |
gru1 | SĂŁo Paulo |
bom1 | Mumbai |
dub1 | Dublin |
(Each provider has its own naming. AWS uses us-east-1. GCP uses us-east1. Azure uses eastus. The shape is the same; the codes differ.)
When you deploy a service “to a region,” it runs in that region’s data center(s). Visitors connect across the public internet; their distance from that region determines their latency.
For a single-region app:
- Users near the region: 20–80ms latency. Feels instant.
- Users far from the region: 200–400ms latency per round trip. Feels sluggish if multiple round trips are needed.
How the edge actually works
“The edge” is a completely different model. Instead of one location running your code, you have hundreds of small nodes — typically in cities you’d recognize: New York, London, Tokyo, Sydney, Mumbai, São Paulo, Auckland.
When a user’s request arrives, DNS-level geographic routing sends them to the nearest edge node. The same JavaScript code runs there, immediately. No “wait for a request to traverse the planet” phase.
Edge nodes are not full virtual machines — they’re typically:
- V8 isolates (Cloudflare Workers, Vercel Edge Functions, Fastly Compute@Edge)
- WASM runtimes (Fastly, some Vercel features)
- Lightweight containers (some newer platforms)
This is why edge compute has constraints:
| Edge | Region (classic serverless / VM) |
|---|---|
| Limited memory (~128 MB typical) | Up to many GB |
| Limited CPU time per request (10-50ms free; up to 30s paid) | Up to minutes |
Web standard APIs only (fetch, crypto, Request, Response) | Full Node.js / Python / etc. |
No filesystem, no child_process | Full OS access |
| Sub-millisecond cold starts | 100–2000ms cold starts |
| Located in 200+ cities | Located in 1 region |
Edge is fast and lightweight; regions are slow but powerful. They’re complementary, not competitors.
The crux: the database lives in a region
Almost every webapp has a primary database — Postgres, MySQL, SQLite, whatever. That database lives in one specific region. It cannot be “everywhere.”
(There are multi-region replicas, but writes still have a primary. And distributed SQL databases like CockroachDB and TiDB exist, but they trade consistency complexity for global reach.)
Once your data is in syd1, your compute has three choices:
1. Co-locate compute with the database (region-pinned)
Pin your functions to syd1. Every database call is fast (1-5ms within the data center). But requests from users far away take longer because the user → function path is now the slow part.
2. Run at the edge
Your code runs in 200+ cities globally. User → code path is fast (5-50ms anywhere). But every database call now traverses to syd1 — which from, say, Frankfurt is ~300ms one way. If your edge function makes 5 database calls per request, you’ve added 1.5 seconds of latency.
3. Hybrid
Most production webapps blend both. Static assets and edge logic at the edge. Database-heavy work in a region near the database. Smart caching at the edge to avoid most database round trips.
A concrete example: same app, three placements
Imagine a simple app with a Postgres database in Sydney that serves users in Sydney, London, and Tokyo. The home page makes 3 sequential database queries.
Placement A — region only (Sydney)
| User location | RTT to Sydney | Database calls | Total latency |
|---|---|---|---|
| Sydney | 5ms | 3 Ă— 2ms | ~16ms |
| London | 320ms | 3 Ă— 2ms | ~340ms |
| Tokyo | 130ms | 3 Ă— 2ms | ~140ms |
Excellent for Sydney users. Awful for London users (every page request takes 340ms+ just on the network).
Placement B — edge only
| User location | RTT to nearest edge | DB calls (edge → Sydney) | Total latency |
|---|---|---|---|
| Sydney | 5ms | 3 Ă— 2ms | ~16ms |
| London | 10ms | 3 Ă— 320ms | ~970ms |
| Tokyo | 8ms | 3 Ă— 130ms | ~400ms |
Slightly faster for Sydney. Significantly worse for London than placement A. Why? The edge runs close to the user, but each database round trip pays the full distance to Sydney.
Placement C — edge + cache
| User location | RTT to nearest edge | DB calls | Total latency |
|---|---|---|---|
| Sydney | 5ms | 0 (cache hit) | ~10ms |
| London | 10ms | 0 (cache hit) | ~15ms |
| Tokyo | 8ms | 0 (cache hit) | ~13ms |
The edge has cached the rendered page. No database calls. Everyone wins.
Cache misses still happen — but only periodically. The 99th-percentile user still benefits from the cached hot path.
This is why ISR (Incremental Static Regeneration), edge caching with revalidation, and CDN caching are so important. They convert region-bound work into edge-bound work, occasionally.
When to use the edge
Edge is the right tool when:
- The work is stateless or cacheable
- The work is fast (< 50ms of CPU per request)
- You need the same code everywhere for consistency
- You want to protect your origin from traffic (auth gates, redirects, A/B tests can all happen at the edge before reaching the origin)
- The user’s geography matters (custom redirects per country, edge personalization)
Classic edge use cases:
- Auth checks (“is this user logged in? if not, redirect to login”)
- A/B testing assignment
- Country-based redirects
- Static page generation with revalidation (ISR)
- Image manipulation on the fly
- Bot blocking and rate limiting
- HTTP header rewrites
- Reading from a cache layer
- Lightweight API endpoints that don’t need a database
When NOT to use the edge
Use region-pinned compute when:
- Heavy database access per request
- Long-running computations (LLM calls, file processing)
- Code that needs Node.js-specific modules (image manipulation with native libs, headless Chrome, FFmpeg)
- Anything stateful (websockets, server-side sessions in memory)
- Anything where < 1MB bundle limits would force unworkable splits
The mistake is thinking “edge = always faster.” It’s only faster if the bottleneck IS the user-to-server distance. If the bottleneck is the database, the edge can make things WORSE.
How to choose a region
Three signals dominate:
1. Where is your database?
The single most important factor. Co-locate compute with the database to minimize the slowest round trips. If your database is in syd1, pin your functions to syd1.
2. Where do your users live?
Roughly. If 80% of your users are in Australia, a Sydney region serves them well. If your users are global, a single region won’t serve everyone well — consider edge + caching, or multi-region replicas.
3. Where do regulations require it?
GDPR pushes EU user data to EU regions. Australian data sovereignty rules push some workloads to Australian regions. HIPAA mandates US healthcare data stays in compliant US regions. Check before deciding.
When in doubt: pick the region where your database lives.
Setting region in practice
The mechanism varies by platform.
Vercel
In vercel.json:
{
"regions": ["syd1"]
}Or per-function via the route config:
// app/api/heavy/route.ts
export const runtime = 'nodejs';
export const preferredRegion = 'syd1';Supabase
You choose the region at project creation. It cannot be changed later — you’d have to create a new project in the new region and migrate. Choose carefully.
AWS (Lambda, RDS, S3)
Region is part of every API call and every resource ARN. Resources cannot move across regions; you’d recreate them.
Cloudflare Workers
Workers run at the edge by default — no region choice. For region-specific work, use Workers + bindings that point to region-specific resources (e.g. a regional Hyperdrive pool for Postgres).
Edge functions on Vercel / Netlify
These run at all edges automatically. You don’t choose; the platform does.
Multi-region — when single-region isn’t enough
For apps with truly global, latency-sensitive needs, the next step is multi-region:
- Read replicas in multiple regions. The primary database is in one place; read-only copies live in others. Reads serve from the nearest replica. Writes still go to the primary.
- Global database systems (CockroachDB, Spanner, PlanetScale Multi-region, Aurora Global, Neon’s read replicas). Strong consistency or eventual consistency across regions, depending on the system.
- Active-active deployments. Multiple primary regions; data sync between them. Complex; possible.
Most webapps don’t need this. The cost and complexity easily outpace the latency benefit. Use it when you’ve genuinely exhausted simpler optimizations.
Common gotchas
-
Default regions are usually wrong for you. Most platforms default to a US region (Vercel:
iad1; AWS:us-east-1). If you’re in Australia, Europe, or Asia, this is the single highest-impact configuration change you can make. -
Region setting is silent — you have to verify. Adding
"regions": ["syd1"]tovercel.jsonrequires a redeploy. Until then, functions still run in the old region. Check the response header (Vercel setsx-vercel-idwhich includes the region). -
Edge functions feel fast in local testing but slow in production. Locally, your laptop runs everything in one place. In production, edge → region (database) latency is real. Always test against deployed infrastructure for performance verification.
-
Cold starts vary dramatically across regions. Less-trafficked regions have colder caches and more frequent cold starts. A function deployed only to
gru1(SĂŁo Paulo) might cold-start more often than one iniad1. -
Multiple regions for the same function multiplies cost. Each deployed region adds invocation overhead. Vercel Pro lets you list multiple regions; running in 3 vs 1 triples some costs.
-
Database connection pooling can backfire in serverless. Each function instance opens its own connections. Without a connection pooler (Supabase’s pgbouncer, PgCat, Hyperdrive), you can exhaust the database’s connection limit. Especially severe with auto-scaling.
-
Edge function bundles must be small. Limits range from 1MB to a few MB depending on platform. Heavy npm dependencies don’t fit. Audit bundle sizes; use tree-shaking aggressively.
-
Cf-Connecting-IP,X-Forwarded-Forand friends matter at the edge. The user’s real IP isn’treq.socket.remoteAddresswhen edge proxies are involved. Each platform exposes the original IP via different headers. -
Geographic IP detection can mislead. Especially with VPNs (popular among privacy-conscious users), the “country” of an IP isn’t necessarily the user’s location. Don’t make critical decisions purely on GeoIP.
-
Egress fees are the silent killer. Moving data across regions or out of a provider’s network costs real money. A misconfigured pipeline that ships data back and forth across continents can cost more than your hosting.
-
Region failures happen. AWS
us-east-1has had several multi-hour outages. A single-region deployment dies with the region. For high-availability apps, plan for failover; for solo projects, accept the rare hours of downtime. -
Date/time / locale handling at the edge. Different edge nodes may have different default locales. Always set timezone and locale explicitly in code rather than relying on server defaults.
-
Compliance is real and unforgiving. GDPR fines are not theoretical. If you process EU personal data, having that data leave the EU even briefly is a violation. Region choice is part of compliance design.
-
Vercel Edge Functions and Cloudflare Workers are similar but not identical. Both are V8 isolate runtimes. APIs differ in detail. Migrating code between them works mostly but not seamlessly.
-
DNS-based geographic routing isn’t perfect. A user in eastern Russia might get routed to Frankfurt instead of Tokyo if their DNS resolver appears to be in Germany. Edge platforms generally do this well, but it’s not magic.
-
Your CDN’s “edge” and your platform’s “edge” might be different concepts. CDN edges typically just cache. Compute edges actually run code. Don’t conflate them; both exist; both matter.
-
Choosing wrong is recoverable, not catastrophic. Most platforms make region changes a few-minutes operation (with the major exception of databases). Don’t agonize for days; pick the best guess, measure, adjust.
See also
- Vercel 🟩 🟦 —
regionsinvercel.json - Cloudflare 🟩 🟦 — Workers are the canonical edge runtime
- Netlify 🟩 🟦 — Deno-based edge functions
- What is hosting? 🟩 — the broader context
- CDNs 🟩 — the cache layer that lets edge work despite region-bound databases
- Supabase 🟩 🟦 — region chosen at project creation
- Postgres 🟩 🟦 — read replicas and connection pooling
- Domains and DNS 🟩 — geographic routing happens here
- Glossary: Region, Edge, Availability zone