Routing Logic for Multi-Region CDN Content Delivery
Within Content Delivery Network Routing Logic, this guide covers deployments with more than one origin region. Multi-region delivery hinges on deterministic routing at the edge: before forwarding to origin, the CDN resolves geographic proximity, latency, and cache topology. Get it wrong and you get cache divergence, stale propagation, and split-brain hydration where APAC users receive EU-cached content during a regeneration window. A predictable routing layer is the foundation of any multi-region Data Fetching & Caching Strategies setup.
Edge evaluation and cache topology
Routing runs independently of the origin fetch cycle. Edge nodes evaluate each request against rules that prioritize geographic proximity, then fall back to latency-based routing when a primary region degrades — using the client ASN, an IP geolocation database, and historical round-trip times. The request goes to the nearest healthy node; on a cache miss, that node makes a controlled origin fetch.
This is the routing decision the edge runs per request:
The fetch must respect regional data residency and align with the broader Content Delivery Network Routing Logic. Without synchronized Cache-Control headers and consistent TTLs, the edge serves mismatched payloads during a regional failover. Enforce header hygiene at the CMS so cache fragments don’t accumulate.
ISR, hydration, and data residency
Frontends fetch through a global load balancer, but Next.js ISR and client hydration add background fetch cycles that can bypass edge routing. If an ISR worker hits a different regional origin than the node serving the user, cache consistency fractures. Pin revalidation endpoints to the same routing topology as the initial fetch to avoid split-brain regeneration.
Frameworks run ISR through background workers that respect regional boundaries, but origin routing must be configured explicitly. The Next.js ISR documentation covers scoping revalidation per region so background updates don’t cross a data-sovereignty boundary.
Deterministic routing via edge middleware
Cloudflare Workers and Vercel Edge Middleware run before the fetch layer. This pattern maps the geo header to a regional CMS endpoint, injects routing metadata, and rewrites the request with explicit cache directives.
// middleware.ts (Next.js / Vercel Edge Runtime)
import { NextRequest, NextResponse } from 'next/server';
const CMS_REGION_MAP: Record<string, string> = {
US: 'https://api.cms-na.example.com/graphql',
DE: 'https://api.cms-eu.example.com/graphql',
JP: 'https://api.cms-apac.example.com/graphql',
};
export function middleware(request: NextRequest) {
// Edge-provided geo header selects the regional origin
const geoRegion = request.headers.get('x-vercel-ip-country') || 'US';
const targetOrigin = CMS_REGION_MAP[geoRegion] || CMS_REGION_MAP['US'];
// Inject routing metadata the CMS can read
const requestHeaders = new Headers(request.headers);
requestHeaders.set('x-cms-region', geoRegion);
requestHeaders.set('x-forwarded-host', new URL(targetOrigin).host);
// Rewrite to the regional CMS
const url = new URL(request.url);
url.host = new URL(targetOrigin).host;
return NextResponse.rewrite(url, {
request: { headers: requestHeaders },
});
}
// Scope to CMS API routes only
export const config = {
matcher: ['/api/cms/:path*', '/_next/data/:path*'],
};
The CMS must honor x-cms-region to return localized data and respect compliance boundaries. Rewriting at the edge instead of proxying through a central origin removes cross-region latency and sheds origin load during spikes.
Cache directives and revalidation windows
Routing is only as good as the directives behind it. Pair region-aware routing with Cache-Control: s-maxage=3600, stale-while-revalidate=86400 — the edge serves cached content for an hour, then refreshes in the background for up to 24 hours, so users never block on a revalidation. This follows the MDN Cache-Control reference.
The CMS must return consistent ETag and Last-Modified validators. Edge nodes use them to decide whether a background fetch is needed; without them, regional nodes trigger redundant origin fetches and defeat the distributed cache.
Validation
Automated testing for headless integrations must verify routing across simulated regions. Inject x-vercel-ip-country or cf-ipcountry with synthetic monitors and assert the response came from the expected regional endpoint. Assert cache validators (x-cache / x-vercel-cache) match expected states — HIT, MISS, STALE, REVALIDATED.
Run these region-specific checks in CI when deploying new schemas or routing rules, so TTLs, headers, and endpoint mappings stay synchronized and cache divergence can’t ship silently.
Region-aware middleware, synchronized TTLs, and validated routing paths are what separate consistent low-latency global delivery from fragmented split-brain failures.
Configuration Reference
| Setting | Value | Purpose |
|---|---|---|
| Region map | country → regional endpoint | Deterministic origin choice per request. |
| Health check | every 10 to 30 s per region | Drives failover before readers see errors. |
| Residency flags | per content type | Marks content that must never be served from another region. |
x-cms-region |
resolved region | Lets origins and ISR workers stay within the request’s topology. |
s-maxage / stale-while-revalidate |
3600 / 86400 | Long edge life; freshness from purges. |
| Validators | ETag and Last-Modified from the CMS |
Cheap revalidation with 304 responses. |
Gotchas & Edge Cases
- Failover versus residency. Automatic failover to the nearest healthy region can violate data residency for regulated content. Mark such content types and fail over only within an allowed set of regions, or serve stale content instead.
- Webhooks from one region. A CMS in one region sends webhooks to one endpoint, but caches exist in all regions. The revalidation route must fan out tag invalidations and purges to every region’s cache.
- Clock skew and
Last-Modified. Regional CMS replicas with slightly different clocks can return validators that make a fresh copy look older. PreferETagbased on content hashes over timestamps. - Preview traffic. Editors in one region previewing content hosted in another region must reach the authoring region directly; route preview by editor session, not by geography.
- Route rewrites leaking hosts. Rewriting to a regional CMS host in middleware exposes that host in responses if error pages include it. Proxy through your own domain and hide origin hosts.
Worked Example
A media group with newsrooms in Europe and Asia ran separate CMS environments per region and a single frontend deployment. During a European evening news peak, the EU origin slowed and the global load balancer shifted APAC editors’ preview traffic and some reader regeneration to the EU cluster, which briefly served European homepage modules to readers in Singapore. The fix pinned regeneration to the x-cms-region of the originating request, restricted failover of homepage content to within the region, and let the edge serve stale homepage copies for up to a day during regional incidents. The next regional slowdown degraded freshness for a few minutes but never crossed content between regions.
Rollout Checklist
- Document which content types are residency-restricted and to which regions.
- Build the region map and health checks, and test failover in staging with one region disabled.
- Pin ISR and revalidation to the region of the triggering request with
x-cms-region. - Fan out webhook invalidations to every region and record per-region results.
- Return
ETagvalidators from every regional origin and verify 304 responses at the edge. - Add synthetic checks from each region that assert the expected regional endpoint served the page.
Test the failover path regularly, not only at launch. Health-based routing that has never been exercised tends to fail in surprising ways during a real incident: a stale DNS record, a missing credential in the secondary region, or a residency rule that blocks the only healthy origin. A quarterly drill that disables one region in staging, and ideally for a few minutes in production during low traffic, keeps the routing logic honest.
Whichever layer you change first, measure before and after with the same instruments: the CDN’s cache-status and Age headers for correctness, real-user TTFB per region for impact, and origin request rate for cost. A routing or caching change that improves one of those at the expense of another is usually a keying mistake, and the three together make it visible within a day of rollout.
Frequently Asked Questions
Do I need regional CMS instances at all?
Usually not for performance: most SaaS CMS delivery APIs already sit behind global CDNs. Regional instances are justified by data residency, editorial independence between regions, or very large write volumes. Without those, one CMS with a global edge is simpler.
How should webhooks reach every region?
Receive the webhook once, verify it, then publish the invalidation to a message channel that each region subscribes to, or call each region’s revalidation endpoint in parallel with retries. Record per-region success so a partial failure is visible.
What should happen when every region is unhealthy?
Serve stale content from the edge using stale-if-error, and show a static maintenance page only for routes that have never been cached. The edge copy is the last line of defence, so make sure the most important routes are always in it.
How do I measure whether regional routing helps readers?
Compare real-user TTFB and LCP per region before and after, from field data rather than synthetic tests. The improvement should be largest for readers far from the previous single origin. If it is not, the edge was probably already serving most requests from cache, and regional origins mainly help cache misses and regeneration.