Back to Blog
Cloud NativeJune 29, 20264 min read

Cloudflare Workers Geo-Routing: Dynamic Traffic Steering for Vercel

Master Cloudflare Workers geo-routing to steer traffic to your nearest Vercel deployment. Reduce latency and optimize performance with edge-based logic.

Cloudflare WorkersVercelGeo-routingEdge ComputingLatencyWeb PerformanceCloudflareDeployment

During a recent infrastructure audit, I noticed that our users in Singapore were consistently hitting our primary Vercel region in US-East. Even with Vercel’s CDN, the initial handshake and server-side processing for our dynamic API routes were adding around 280ms of unnecessary latency. We needed a way to force traffic to a closer region, and Cloudflare Workers geo-routing proved to be the most surgical tool for the job.

If you've already explored Vercel Blue-Green Deployment: Routing Traffic with Cloudflare, you know that the edge is the best place to make routing decisions before they ever hit your origin.

Why Geo-Routing at the Edge?

Vercel provides excellent global distribution, but for complex applications, you often maintain regional backend deployments to comply with data residency laws or to keep database proximity high. Instead of relying on client-side redirects or DNS-based steering—which can be slow to propagate—we can intercept the request at the edge.

By using Cloudflare Workers, we inspect the cf.country property in the request object. This allows us to make sub-millisecond decisions about where that request should ultimately land.

Setting Up the Architecture

The setup is straightforward. You deploy your application to multiple Vercel regions (e.g., us-east-1 and asia-southeast-1) and use a Cloudflare Worker to act as the traffic controller.

JAVASCRIPT
addEventListener(CE9178">'fetch', event => {
  event.respondWith(handleRequest(event.request))
})

async function handleRequest(request) {
  const country = request.cf.country;
  const url = new URL(request.url);

  // Define your regional mapping
  let targetDomain = CE9178">'us-east.myapp.com';
  
  if ([CE9178">'SG', CE9178">'JP', CE9178">'AU'].includes(country)) {
    targetDomain = CE9178">'asia.myapp.com';
  }

  url.hostname = targetDomain;

  return fetch(url.toString(), {
    method: request.method,
    headers: request.headers,
    body: request.body
  });
}

The Trade-offs of Latency-Based Traffic Steering

We initially tried to handle this using Cloudflare’s Load Balancer geo-steering. While it’s robust, it lacks the fine-grained control we needed for specific API headers. We also considered Edge-Side A/B Testing: Routing Traffic Between Vercel and Cloudflare Workers, but that requires a more complex state management system.

The Worker approach is cheaper and gives us total control over the request lifecycle. However, keep in mind that you are now introducing an extra hop in the request chain. If your Worker logic is too heavy, you negate the latency gains. Keep your logic simple: lookup, map, forward.

Comparing Routing Strategies

StrategyComplexityLatency ImpactControl Level
DNS SteeringLowHigh (TTL lag)Minimal
CF Load BalancerMediumLowModerate
Cloudflare WorkersHighVery LowFull

Avoiding the "Waterfall" Trap

One major pitfall is accidentally increasing your critical request chain. As I discussed in Critical Request Chain Optimization: Reducing Waterfall Latency, every additional redirect or header modification can stall the browser.

When you implement Cloudflare Workers geo-routing, ensure you are performing a transparent proxy (as shown in the code above) rather than a 302 redirect. A redirect forces the client to perform a new DNS lookup and TCP handshake, which is exactly what we are trying to avoid.

Key Considerations for Production

  1. Cache Keys: If you are caching responses, ensure your Cache-Key includes the CF-IPCountry header. Otherwise, a user in Tokyo might get a cached response intended for a user in New York.
  2. Vercel Domains: Ensure your regional Vercel deployments are correctly configured to handle the incoming Host headers. You may need to adjust your Vercel vercel.json to allow custom domains per region.
  3. Testing: Use the cf-trace endpoint to verify that your worker is correctly identifying the country code during local development or staging.

I’m still experimenting with whether it makes sense to offload more logic to the edge, especially as I continue Deploying Next.js 16 to Cloudflare Workers with OpenNext. While routing is a solved problem, stateful regional data synchronization remains the real challenge. Next time, I’d probably look into using Workers KV to store the regional map, allowing us to update routing rules without redeploying the Worker code itself.

Frequently Asked Questions

Does Cloudflare Workers geo-routing work on the Free plan? Yes, the request.cf object is available on all Cloudflare plans, including the Free tier.

Will this interfere with Vercel's built-in CDN? It acts as a layer in front of it. Your Worker will fetch from the Vercel domain, and Vercel will still cache the response at its own edge, so you get the benefits of both.

How do I handle requests where the country cannot be determined? Always provide a sensible default (the "primary" region) in your code to ensure the application remains functional if the geo-IP lookup fails.

Similar Posts