Vercel Blue-Green Deployment: Routing Traffic with Cloudflare
Master Vercel blue-green deployment strategies using Cloudflare Workers for seamless traffic routing and zero-downtime releases at the edge.
When we moved our main marketing site to a high-frequency release cycle, Vercel’s default deployment model—while excellent—felt slightly too binary for our needs. We wanted the ability to warm up a production-ready environment and flip the switch for 100% of our users instantly, rather than relying on standard preview URLs. That’s when we started using Cloudflare Workers to handle the traffic orchestration.
Achieving a true Vercel blue-green deployment requires moving the routing logic out of the hosting provider and onto the edge. By treating Vercel instances as "Blue" (current) and "Green" (next) origins, you gain total control over the release lifecycle.
The Problem with Standard Deployments
Initially, we tried using Vercel’s built-in preview deployments. They’re great for QA, but they don't provide a clean way to "promote" a preview to production without triggering a new build or DNS propagation delays. We needed a way to keep two distinct production-grade environments alive simultaneously.
We first tried hard-coding environment variables to toggle features, but that leaked "Green" code into the "Blue" environment’s edge cache. It was messy. We needed a separate origin, which led us to Edge-Side A/B Testing: Routing Traffic Between Vercel and Cloudflare Workers. Once you understand how to split traffic, the jump to blue-green is minor.
Setting Up the Architecture
You’ll need two separate Vercel projects (or two distinct deployment domains). Let’s call them blue.example.com and green.example.com. Your primary domain, www.example.com, will point to a Cloudflare Worker that acts as your traffic controller.
The Worker logic is straightforward. It inspects a header or a cookie to decide which origin to fetch content from.
JAVASCRIPT// Cloudflare Worker script addEventListener(CE9178">'fetch', event => { event.respondWith(handleRequest(event.request)) }) async function handleRequest(request) { const url = new URL(request.url) // Check for a deployment cookie to force green environment const cookie = request.headers.get(CE9178">'cookie') const target = (cookie && cookie.includes(CE9178">'env=green')) ? CE9178">'https://green.example.com' : CE9178">'https://blue.example.com' const newUrl = new URL(url.pathname + url.search, target) return fetch(newUrl, request) }
Why Use Cloudflare Workers for Routing?
The beauty of this approach is the speed. Because the routing happens at the edge, the overhead is usually around 20-40ms—barely perceptible to the end user. Compared to traditional load balancers, you’re saving a round trip to your origin servers.
If you’re managing complex state, remember that Next.js Blue-Green Deployment: Managing Server Component Schema Evolution is a hurdle you'll eventually hit. If your "Green" deployment changes the API contract for Server Components, you must ensure your data layer supports both versions simultaneously.
Comparison of Deployment Strategies
| Strategy | Complexity | Rollback Time | Infrastructure Cost |
|---|---|---|---|
| Standard Vercel | Low | Minutes (Rebuild) | Low |
| Canary (Vercel) | Medium | Seconds | Medium |
| Edge-Routed Blue-Green | High | Instant | Medium-High |
Practical Implementation Steps
- Prepare the Environments: Deploy your code to two separate Vercel projects. Ensure that environment variables (API keys, secrets) are synced, but allow for distinct
NEXT_PUBLIC_variables if needed for debugging. - Configure the Worker: Set up the Cloudflare Worker as a "Route" on your primary domain (
example.com/*). - Warm-up: Before flipping the switch, verify the Green environment by accessing it via a bypass cookie or a specific header.
- The Switch: Update the Worker’s logic to point to the Green origin. Because it's a code change in the Worker, it propagates globally in about 30 seconds.
Lessons Learned
We initially encountered issues with stale cache headers. If your Vercel project sends s-maxage headers, Cloudflare might cache the "Blue" response even after you've updated the worker to route to "Green." We had to explicitly set Cache-Control: no-cache on the Worker for the initial transition phase to ensure users saw the new build immediately.
Also, don't forget that this strategy is essentially a manual override. If you need a more automated approach for Canary releases, I recommend looking into Next.js Traffic Shadowing: Architecting Canary Releases at the Edge to safely test production traffic without impacting the user experience.
FAQ
Does this affect SEO? Yes, if not handled correctly. Ensure your canonical tags in the HTML point to the primary domain, not the specific blue/green subdomains.
How do I handle database migrations during a blue-green switch? This is the hardest part. You must use an "expand-and-contract" pattern. The database schema must be backward compatible so that both "Blue" and "Green" code can read/write to it simultaneously.
Is this overkill for small projects? Probably. If you have a single-developer team, Vercel’s standard deployment workflow is almost certainly sufficient. This pattern is for teams that need high availability and instant rollbacks.
I’m still experimenting with how to automate the "flip" using a Cloudflare KV store so I don't have to redeploy the Worker every time I want to toggle environments. Next time, I’ll likely build a small dashboard that updates the KV value, making the production switch a single-click operation.