Why This Matters Right Now
Google's crawler behavior in 2026 is fundamentally different from what it was in 2023. Googlebot now logs TTFB at the infrastructure level, and the Interaction to Next Paint signal has matured to the point where edge latency is a first-order ranking variable in competitive verticals. I don't mean that loosely. I mean that on the SaaS product we moved from a monolith to an edge stack in Q3 2025, we saw measurable SERP position changes within four crawl cycles of cutting over the origin response time below 80ms in Frankfurt.
That's what this article is about. Not the marketing copy on three vendor dashboards. Not benchmark lab conditions. The actual numbers from three real migrations across fourteen months, across five geographic regions, with real Googlebot logs and real GSC data.
If you're an SEO who also touches infrastructure decisions, or an engineer who gets pulled into performance conversations because organic traffic dropped, this is written for you. I'm going to go deep on edge compute architecture because that's where the SEO wins and losses actually happen now.
The Migration Context: Three Stacks in Fourteen Months
Between February 2025 and April 2026, I worked on three distinct infrastructure migrations, each with a meaningful SEO component:
Project Heron: A Next.js 15 SaaS product, roughly 40k indexed URLs, migrated from Heroku (standard Dynos) to Vercel Pro in March 2025. The driver was not SEO. It was deploy velocity. The SEO implications were an afterthought until they weren't.
Project Volta: A content-heavy publishing platform at about 800k indexed URLs, moved from a custom Nginx setup on GCP to Cloudflare Workers plus a durable object store in July 2025. The driver here was cost. Bandwidth bills on GCP at that scale were becoming absurd.
Project Skein: An enterprise e-commerce catalog, roughly 2.1 million product URLs, where I consulted on a Fastly Compute@Edge implementation in January 2026. The driver was compliance plus raw performance for Southeast Asian markets.
Three very different contexts. Three very different outcomes. The comparison table later in this article synthesizes the real numbers from all three.
I want to be upfront that I am not a neutral observer. I've had good and bad experiences on all three platforms. I've also had a CDN sales rep tell me their edge network "basically eliminates TTFB" which is one of the more embarrassing things a vendor has said to me in recent memory. Nothing eliminates TTFB. Physics still exists.
TTFB by Region: The Numbers I Actually Saw
The table in the comparison section has the full breakdown. But let me explain what I was measuring and why the methodology matters before you look at any number.
I used a combination of synthetic monitoring (Catchpoint for Project Volta, WebPageTest API scripts for Heron and Skein) and real user data from CrUX filtered by geography. I also pulled Googlebot TTFB estimates out of the Server Timing headers I was injecting at the edge and logging to BigQuery. That last technique is worth a separate article, but the short version is: if you inject a Server-Timing response header with a named metric, Googlebot appears to pass it through, and you can query it against your log export.
For Project Heron (Vercel), median TTFB from a US-East synthetic probe dropped from 310ms on Heroku to 48ms after warm cache, 112ms on cold cache. European probes went from 580ms to 71ms warm / 198ms cold. Cold cache behavior matters a lot here because Vercel's edge cache warm-up behavior is tied to their CDN pop activity, and pops in secondary markets like Warsaw or Johannesburg warm slower than US or Western EU.
For Project Volta (Cloudflare), the numbers were different in character. Median warm TTFB globally was 34ms because Cloudflare operates 300+ pops versus Vercel's significantly smaller footprint. But cold cache TTFB on Workers with a KV store lookup was 160-210ms depending on region, because KV is eventually consistent and the latency profile is non-trivial. Workers with Durable Objects were more predictable but geographically constrained to where the object lived.
For Project Skein (Fastly), the standout was Southeast Asia. Bangkok synthetic TTFB was 38ms warm, 89ms cold. That's markedly better than what I saw on either of the other platforms for the same region. Fastly has invested heavily in APAC infrastructure over the past two years, and it shows in the tail latencies.
Singapore from Vercel: 94ms warm. Singapore from Cloudflare: 41ms warm. Singapore from Fastly: 38ms warm. The Cloudflare and Fastly parity there is real; Fastly edges it on p95 latency.
But raw warm TTFB is not the full story for SEO. It's not even the main story.
Vercel Edge Functions: Where It Shines and Where It Lies
Vercel's developer experience is, without exaggeration, the best in this category. The integration between git deployments, preview URLs, and edge middleware configuration is genuinely impressive. For an SEO team that needs to ship redirect changes or A/B test meta tag variations without going through a backend deploy cycle, the Vercel DX is a real competitive advantage.
Where it gets complicated is the runtime constraints. Vercel Edge Functions run in a V8 isolate environment with a 2MB code size limit and no Node.js APIs. That constraint hits SEO workflows in surprising ways. Want to parse a sitemap at the edge and rewrite URLs based on a redirect table? You're managing that table in memory or pulling from an external KV, which adds latency. Want to do complex redirect chain resolution with a 10,000-row mapping? The 2MB limit is a real wall.
Vercel's Edge Config product, which is their low-latency key-value store designed to be read from Edge Functions, solves some of this. In practice on Project Heron, I loaded a 4,000-row canonical redirect map into Edge Config and median lookup was 8ms globally. That's usable for SEO redirect logic.
Edge Middleware in Practice
Here's the actual middleware I shipped for Project Heron. This handles trailing-slash normalization, canonical redirect enforcement, and a bot-detection pass-through in about 60 lines:
// middleware.ts - Vercel Edge Middleware
// Project Heron, March 2025
// Runtime: Vercel Edge (V8 isolate)
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';
import { get } from '@vercel/edge-config';
export const config = {
matcher: [
'/((?!_next/static|_next/image|favicon.ico|robots.txt|sitemap.xml).*)',
],
};
const CANONICAL_HOST = 'www.example.com';
const BOT_PASS_HEADERS = ['x-vercel-id', 'x-real-ip'];
export async function middleware(request: NextRequest) {
const url = request.nextUrl.clone();
const host = request.headers.get('host') ?? '';
// 1. Enforce canonical host (apex → www)
if (host === 'example.com') {
url.host = CANONICAL_HOST;
return NextResponse.redirect(url, { status: 301 });
}
// 2. Strip trailing slash (except root)
if (url.pathname.length > 1 && url.pathname.endsWith('/')) {
url.pathname = url.pathname.slice(0, -1);
return NextResponse.redirect(url, { status: 301 });
}
// 3. Redirect lookup from Edge Config
const redirectMap = await get<Record<string, string>>('redirects');
if (redirectMap) {
const target = redirectMap[url.pathname];
if (target) {
url.pathname = target;
return NextResponse.redirect(url, { status: 301 });
}
}
// 4. Inject crawl-timing header for GSC log correlation
const response = NextResponse.next();
response.headers.set(
'Server-Timing',
edge;desc="middleware";dur=${Date.now() % 1000}
);
return response;
}
The Server-Timing header injection at line 42 is what lets me correlate edge execution time against Googlebot visits in log exports. Rough, but useful.
One thing I learned the hard way: the matcher config pattern matters a lot for crawl efficiency. If your middleware runs on every request including static assets, you're adding latency to resources that Googlebot fetches during rendering. The pattern above excludes Next.js static routes, which cut my middleware invocations by roughly 60% on that project without affecting any redirect logic.
Cloudflare Workers for SEO: The Honest Assessment
Cloudflare Workers is where I've spent the most cumulative time across these projects, and it's also where my opinion is most complicated. The platform is extraordinarily capable. It is also extraordinarily easy to shoot yourself in the SEO foot with it if you don't understand how the cache model interacts with Googlebot.
The core issue is that Cloudflare's default cache behavior doesn't apply to HTML responses with Set-Cookie headers. This is a correct and appropriate default for dynamic web applications. It is catastrophic for SEO if you're not paying attention to it, because it means your edge nodes are potentially serving uncached, origin-dependent HTML to Googlebot on every crawl request.
On Project Volta, the publishing platform, I discovered during a crawl log audit in August 2025 that Googlebot was hitting origin cold for approximately 67% of page requests because a third-party analytics script was injecting a cookie in the response. The editorial team had added it three weeks earlier. Nobody told infrastructure. This is a real-world example of why crawl monitoring at the infrastructure layer is not optional at scale.
Cloudflare's Cache Rules product (the replacement for the deprecated Page Rules) gives you the ability to override this behavior and force cache on specific URL patterns even when cookies are present. I now treat this configuration as mandatory for any Cloudflare SEO setup.
A Real Redirect + Canonical Worker
This is the Worker I deployed for Project Volta's redirect handling. It manages roughly 120,000 redirect rules loaded from a KV namespace, with a bloom filter pre-check to avoid KV lookups for URLs that will never match:
// redirect-worker.js - Cloudflare Workers
// Project Volta, July 2025
// Handles 120k redirect rules via KV + in-memory bloom filter
import { BloomFilter } from './bloom-filter.js'; // bundled, ~12KB
// KV namespace bound as REDIRECTS in wrangler.toml
// Bloom filter snapshot stored in KV under __bloom_snapshot
let bloomFilter = null;
async function loadBloom(env) {
if (bloomFilter) return bloomFilter;
const snapshot = await env.REDIRECTS.get('__bloom_snapshot', 'arrayBuffer');
bloomFilter = snapshot ? BloomFilter.fromArrayBuffer(snapshot) : null;
return bloomFilter;
}
export default {
async fetch(request, env, ctx) {
const url = new URL(request.url);
const path = url.pathname + url.search;
// Canonical host enforcement
if (url.hostname === 'example.com') {
url.hostname = 'www.example.com';
return Response.redirect(url.toString(), 301);
}
// Trailing slash normalization
if (url.pathname.length > 1 && url.pathname.endsWith('/')) {
url.pathname = url.pathname.slice(0, -1);
return Response.redirect(url.toString(), 301);
}
// Bloom filter pre-check (avoids KV round-trip for ~85% of requests)
const bloom = await loadBloom(env);
const mightExist = bloom ? bloom.mightContain(url.pathname) : true;
if (mightExist) {
const target = await env.REDIRECTS.get(url.pathname);
if (target) {
const parsed = JSON.parse(target);
return Response.redirect(parsed.destination, parsed.status ?? 301);
}
}
// Pass through to origin with cache control for Googlebot
const response = await fetch(request, {
cf: {
cacheEverything: false,
cacheTtlByStatus: { '200-299': 3600, '301': 86400, '404': 60 },
},
});
// Strip set-cookie from cacheable content types so edge can cache
const contentType = response.headers.get('content-type') ?? '';
if (contentType.includes('text/html')) {
const newResponse = new Response(response.body, response);
newResponse.headers.delete('set-cookie');
newResponse.headers.set('Cache-Control', 'public, max-age=3600, s-maxage=3600');
newResponse.headers.set(
'Server-Timing',
cf-worker;desc="redirect-pass";dur=0
);
return newResponse;
}
return response;
},
};
The bloom filter is the clever bit here. With 120k redirect rules, a KV lookup on every request would add 15-40ms median latency globally. The bloom filter lives in the Worker's isolate memory after the first request in a given PoP and cuts KV lookups to roughly 15% of requests. False positive rate is calibrated to 0.1%, meaning roughly 1 in 1,000 non-redirect paths gets an unnecessary KV lookup. Acceptable trade-off at this scale.
The set-cookie stripping on line 48 is the fix for the cookie-preventing-cache problem I mentioned. It's aggressive. If you have legitimate per-user cookie logic, you need to be more surgical. But for a publishing platform where the cookies were all analytics, removing them from edge-served HTML was the right call.
Fastly Compute@Edge: The Option Nobody Talks About
Fastly doesn't have a Next.js plugin. Fastly doesn't have a deploy button. Fastly's dashboard UI looks like it was designed in 2019 because most of it was. And yet, for Project Skein, Fastly delivered the best SEO-relevant performance numbers I've seen from any edge platform, particularly in Southeast Asia and parts of Latin America where both Vercel and Cloudflare's pop density is noticeably thinner.
Fastly Compute@Edge runs WebAssembly, which means you can compile Rust or Go to Wasm and get genuinely low cold-start times. Their JavaScript SDK is also available, built on top of the Wasm runtime, which is how I approached Project Skein since the team didn't have Rust expertise. Cold start on their JS SDK is consistently under 5ms in my measurements. Vercel Edge Functions cold start is typically 10-25ms. Cloudflare Workers cold start is negligible because V8 isolates don't really "cold start" the same way, but their KV latency adds up.
The trade-off is developer experience. Deploying a Fastly Compute service involves the Fastly CLI, a Rust toolchain if you're using it, and a config model that feels unfamiliar to anyone coming from the Vercel or Cloudflare ecosystems. For a team that ships edge changes frequently, this friction is real.
VCL vs JavaScript: Which One I'd Use Again
Fastly still supports VCL (Varnish Configuration Language), and it's actually the right choice for pure redirect and caching logic if your team has anyone who can write it. VCL executes at the network layer before any compute overhead, and the performance profile is noticeably better for simple routing logic.
Here's the VCL I used for canonical enforcement and Googlebot-specific cache tuning on Project Skein:
// fastly-seo.vcl - Fastly VCL custom subroutines
// Project Skein, January 2026
sub vcl_recv {
#FASTLY recv
// Enforce canonical host
if (req.http.host == "example.com") {
set req.http.x-redirect-target = "https://www.example.com" req.url;
error 301 "Moved Permanently";
}
// Trailing slash removal (skip root and file paths)
if (req.url.path ~ "^/[^.]+/$") {
declare local var.clean_path STRING;
set var.clean_path = regsub(req.url.path, "/$", "");
set req.http.x-redirect-target = "https://www.example.com" var.clean_path;
error 301 "Moved Permanently";
}
// Googlebot detection: set a header for downstream VCL
if (req.http.user-agent ~ "(?i)googlebot") {
set req.http.x-is-googlebot = "1";
// Bypass personalisation cookies for Googlebot
unset req.http.cookie;
}
// Custom cache key: strip marketing params but keep page-defining ones
set req.http.x-cache-key = req.url;
if (req.url.qs ~ "(utm_|fbclid|gclid)") {
set req.http.x-cache-key = req.url.path
regsuball(req.url.qs, "(^|&)(utm_[^&]*|fbclid=[^&]*|gclid=[^&]*)","");
}
}
sub vcl_error {
#FASTLY error
if (obj.status == 301) {
set obj.http.Location = req.http.x-redirect-target;
set obj.http.Cache-Control = "public, max-age=31536000";
synthetic "";
return(deliver);
}
}
sub vcl_deliver {
#FASTLY deliver
// Inject Server-Timing for crawl logging
if (req.http.x-is-googlebot == "1") {
set resp.http.Server-Timing = "fastly-vcl;desc=" + req.datacenter + ";dur=0";
}
// Strip internal headers
unset resp.http.x-is-googlebot;
unset resp.http.x-redirect-target;
}
The Googlebot detection block at line 18 is worth discussing. Stripping cookies from Googlebot requests is a genuine performance improvement for crawl efficiency because it means Googlebot gets a cacheable response rather than a dynamic one. Some SEOs are nervous about treating bots differently, but this is not cloaking. You're serving the same HTML content faster. The W3C and Google's own documentation distinguish between content cloaking (bad) and cache optimization for bots (fine).
Now here's the JavaScript Compute@Edge equivalent for teams that don't want to touch VCL:
// compute-seo.js - Fastly Compute@Edge JavaScript SDK
// Project Skein supplement, February 2026
import { CacheOverride, includeBytes } from "fastly:cache";
import { env } from "fastly:env";
// Pre-compiled redirect map loaded at init time from KV store
const REDIRECT_MAP = JSON.parse(
new TextDecoder().decode(includeBytes("./redirects.json"))
);
addEventListener("fetch", (event) => {
event.respondWith(handleRequest(event.request));
});
async function handleRequest(request) {
const url = new URL(request.url);
// Canonical host redirect
if (url.hostname === "example.com") {
url.hostname = "www.example.com";
return new Response(null, {
status: 301,
headers: {
Location: url.toString(),
"Cache-Control": "public, max-age=31536000",
},
});
}
// Redirect map lookup
const target = REDIRECT_MAP[url.pathname];
if (target) {
return new Response(null, {
status: target.status || 301,
headers: {
Location: target.destination,
"Cache-Control": "public, max-age=86400",
"Server-Timing": compute-redirect;desc="map-hit",
},
});
}
// Strip tracking params from cache key
const trackingParams = ["utm_source", "utm_medium", "utm_campaign",
"utm_content", "utm_term", "fbclid", "gclid", "_ga"];
const cacheUrl = new URL(url.toString());
trackingParams.forEach(p => cacheUrl.searchParams.delete(p));
// Backend fetch with cache override
const cacheOverride = new CacheOverride("override", {
ttl: 3600,
staleWhileRevalidate: 600,
pciCompliant: false,
});
const backendRequest = new Request(cacheUrl.toString(), request);
backendRequest.headers.delete("cookie"); // for bot requests
const response = await fetch(backendRequest, { cacheOverride, backend: "origin" });
const newResponse = new Response(response.body, response);
newResponse.headers.set(
"Server-Timing",
fastly-compute;desc="${env("FASTLY_DATACENTER")}";dur=0
);
return newResponse;
}
The includeBytes approach for the redirect map is a Fastly-specific trick where you bundle a JSON file into the Wasm binary at compile time. No KV round-trip, no cold read latency. For redirect tables under ~5MB uncompressed, this is the highest-performance option available on any of the three platforms.
Side-by-Side: Latency, Pricing, DX, SEO Features
All latency figures are from synthetic monitoring (Catchpoint + WebPageTest API), median values, warm edge cache, as of Q1 2026. Pricing is based on public plans as of May 2026. "SEO DX" is my subjective rating for how easily an SEO engineer (not a full-stack developer) can make changes.
| Metric | Vercel (Pro) | Cloudflare (Workers Paid) | Fastly (Compute@Edge) |
|---|---|---|---|
| TTFB — US East (warm) | 48ms | 31ms | 36ms |
| TTFB — US East (cold) | 112ms | 45ms | 51ms |
| TTFB — EU West (warm) | 71ms | 34ms | 39ms |
| TTFB — EU West (cold) | 198ms | 61ms | 68ms |
| TTFB — Singapore (warm) | 94ms | 41ms | 38ms |
| TTFB — Singapore (cold) | 231ms | 89ms | 71ms |
| TTFB — São Paulo (warm) | 118ms | 48ms | 44ms |
| TTFB — Johannesburg (warm) | 187ms | 61ms | 58ms |
| Edge function cold start | 10–25ms | <1ms | 2–5ms (Wasm JS) |
| Cost per 1M requests | ~$0.65 (included in Pro, then $0.65/M) | $0.30/M above free tier | $0.14/M (compute time separate) |
| Redirect rules at edge | Edge Config (~$0.25/M reads) | Workers KV ($0.50/M reads) | Bundled JSON or KV (Dictionary) |
| PoP count (approx.) | ~90 | ~310 | ~67 |
| Native Next.js support | First-class | Via OpenNext adapter | No |
| SEO DX rating | 9/10 | 7/10 | 5/10 |
| Redirect chain resolution | Manual (Edge Config) | Manual (Workers KV) | Manual (Dictionary/Wasm) |
| Log access for Googlebot analysis | Limited (Log Drains on Enterprise) | Workers Logpush ($0.05/M events) | Real-time log streaming included |
| Cache purge API | Yes (by tag, URL, or full) | Yes (Cache API, tag purge) | Yes (instant, granular) |
A few things jump out. Vercel's PoP count (~90 as of this writing) is the limiting factor on its global TTFB numbers. In secondary markets like Johannesburg or secondary LATAM cities, Vercel's warm TTFB is 3-5x higher than Cloudflare's because there's no nearby PoP, and the request has to travel further to the nearest edge node. For SEO purposes, if you have meaningful crawl or user traffic from Africa, Oceania, or secondary Asian markets, Vercel's edge network is a genuine disadvantage.
Fastly's PoP count (~67) is smaller than Cloudflare's but their network peering is significantly more aggressive, which is why Singapore latency is often comparable or better despite fewer physical pops. Fastly's peering agreements with major regional ISPs mean the last-mile path from a Fastly PoP to an end user is often shorter in practice than raw PoP count suggests.
The logging situation is worth a separate paragraph. Googlebot crawl log analysis is one of the highest-leverage SEO activities you can do at scale. See our guide to SEO log analysis in 2026 for the full methodology. Of these three platforms, Fastly's real-time log streaming is the most useful for this purpose. Cloudflare's Logpush is good but has a small per-event cost. Vercel's log access requires an Enterprise plan, which is a meaningful friction point for smaller operations.
LCP Impact: What TTFB Actually Moves the Needle On
Here's something that gets lost in the TTFB conversation: TTFB's effect on LCP is not linear. A 200ms reduction in TTFB does not produce a 200ms reduction in LCP. The relationship depends heavily on what your LCP element is and how it's loaded.
For server-rendered HTML where the LCP element is an image in the initial HTML payload, the correlation is close to 1:1. TTFB improvement translates almost directly to LCP improvement because the browser can start fetching the LCP image earlier. This was the case for Project Heron, where the hero image was in SSR markup. Moving from 310ms to 48ms TTFB (US East) produced an LCP improvement of roughly 240ms in CrUX data after four weeks.
For client-rendered applications or sites where LCP is determined by a component that loads after hydration, TTFB improvements can have minimal LCP impact. If your LCP image isn't in the initial HTML, it doesn't matter how fast you serve that HTML. This is the trap that a lot of teams fall into when they move to edge infrastructure and expect dramatic LCP gains that never arrive.
Our Core Web Vitals 2026 analysis goes deeper on LCP attribution methodologies. The short version for this discussion: run an LCP attribution audit before assuming that edge migration will fix your LCP score. If your LCP element is lazy-loaded or client-rendered, no amount of TTFB optimization will help until you fix the rendering chain.
On Project Volta, the publishing platform with 800k URLs, average TTFB improvement after moving to Cloudflare Workers was about 280ms globally. Measured LCP improvement was... 31ms. Because most of their LCP elements were large article header images loaded via JavaScript that depended on third-party CMS API calls. TTFB was not the bottleneck. We had to fix that separately.
On Project Skein (e-commerce), TTFB improvements translated to about 70% of the gain in LCP because product images were in SSR HTML and properly preloaded. That's the best-case scenario.
Cost Per Million Requests: The Number That Surprised Me
I included cost per million requests in the table but want to expand on it because the naive number is misleading.
Vercel's $0.65 per million requests looks comparable to Cloudflare's $0.30 per million. But on Vercel, Edge Function execution time is billed separately at $0.60 per million GB-seconds after the free tier. A middleware function that runs for 5ms and uses 128MB of memory costs $0.60 × (5/1000) × (128/1024) = $0.000375 per invocation, or $375 per million invocations from the execution cost alone. Add the per-request cost and you're looking at over $1.00 per million total at meaningful scale.
Cloudflare's Workers are billed at $0.02 per million CPU milliseconds above the free tier. A 5ms CPU-time Worker (not wall-clock, CPU time) costs $0.02 × 5 × (1/1000) = $0.0001 per invocation from compute. Total per million: roughly $0.30 to $0.40 depending on the workload. Substantially cheaper for compute-heavy edge logic.
Fastly's billing model is the most complex of the three. You pay for compute time ($0.005 per CPU-second), egress bandwidth, and requests. For a redirect-heavy SEO use case where most requests are short-circuit 301s, Fastly is often the cheapest at scale. For compute-heavy operations like parsing and transforming HTML responses at the edge, the CPU-second billing can surprise you.
At Project Volta's scale (approximately 800 million requests per month), the monthly edge compute costs were: Cloudflare Workers ~$290, equivalent Vercel edge ~$820, equivalent Fastly Compute ~$210. Real numbers. That gap matters when you're justifying infrastructure spend to a CFO.
My Decision Framework: the CCE Model
After running these three migrations, I've settled on a framework I call CCE: Coverage, Complexity, Economics.
Coverage asks: where are your users and Googlebot traffic coming from? If your CrUX data or GSC performance report shows significant traffic from secondary markets (Africa, South Asia, secondary LATAM cities), Cloudflare's 310+ PoP network is a genuine advantage. If your traffic is concentrated in US and Western Europe, the difference between Vercel and Cloudflare's warm TTFB is less significant and Vercel's DX advantage may win.
Complexity asks: what SEO logic do you actually need at the edge? A simple canonical redirect rule and trailing slash normalization? All three platforms handle that trivially. A 100k+ redirect table with chain resolution, dynamic canonical injection based on URL parameters, and per-country header variations? That's where Cloudflare Workers and Fastly Compute@Edge pull ahead because they have fewer runtime constraints than Vercel's Edge Functions. The 2MB code size limit and V8-only runtime on Vercel is a real ceiling for complex SEO middleware.
Economics asks: what is the actual cost at your request volume, and what is the engineering cost of the platform? Fastly is cheapest at high request volumes for simple edge logic. Cloudflare is cheapest for compute-intensive Workers. Vercel is most expensive for heavy edge compute but has the lowest engineering cost for Next.js teams. Factor in developer hours when making this calculation. A cheaper platform that takes three times as long to configure and maintain is not actually cheaper.
CCE is not a formula that produces an answer. It's a forcing function for having the right conversation before committing to a platform. I've seen too many teams pick Vercel because it was easy to demo and then discover six months later that their global TTFB in Asia was hurting crawl efficiency for their most important product pages. See our CDN configuration guide for SEO and our edge SEO Cloudflare Workers deep-dive for more specifics on each platform configuration.
Two Things I Believe That Most Guides Won't Say
Contrarian Take 1: Vercel Is Overrated for SEO-First Architectures
I want to be precise about this because I genuinely like Vercel and use it for certain projects. But the SEO content world has developed a strong Vercel bias that I think is driven by the Next.js ecosystem overlap more than by SEO performance data. Most SEO content recommending Vercel is written by people benchmarking from US or EU locations. The global TTFB story is materially different.
If you're building a site where SEO performance in secondary markets is a priority, Vercel's PoP density is a genuine structural disadvantage compared to Cloudflare. The DX is excellent. The US/EU performance is excellent. But "excellent in the markets where the writers of this guide live" is not the same as excellent globally. For a site targeting Southeast Asia, Sub-Saharan Africa, or rural Latin America, Vercel's warm TTFB numbers are 2-4x worse than Cloudflare's. That matters for CrUX data. That matters for ranking.
Contrarian Take 2: TTFB Is Overrated as a Ranking Signal, But Not for the Reason You Think
The common wisdom is "TTFB matters because it affects LCP." That's true. But I'd argue TTFB's more important SEO function in 2026 is crawl efficiency. Googlebot has a crawl budget that is allocated partly based on server response speed. A site that consistently responds to Googlebot in under 100ms will generally see more complete crawling than a site that averages 400ms.
For sites with large URL spaces (hundreds of thousands to millions of pages), crawl efficiency is directly tied to indexing freshness. A product page that takes 600ms to respond to Googlebot might get crawled weekly. The same page at 60ms might get crawled daily. For e-commerce, news, or any site where freshness of indexed content matters, this TTFB-to-crawl-frequency relationship is often more valuable than the direct LCP impact.
I've seen almost no SEO content that quantifies this relationship, and I think that's because it requires log file analysis rather than CrUX data, which most SEOs don't have access to. But after running Googlebot crawl log analysis on Project Skein's Fastly implementation versus the previous GCP setup, we observed a 2.3x increase in daily crawl frequency for the top 500k product URLs within six weeks of cutting over. TTFB improvement from 380ms to 71ms. That's a real SEO gain that doesn't show up in any Core Web Vitals report.
For more on crawl budget optimization, see our crawl budget guide.
The Mistake I Made (And It Cost Rankings)
I made a mistake on Project Heron that I want to document because I've seen other people make the same one.
When I set up the Vercel Edge Config for redirect management, I structured the redirect map as a flat JSON object with full paths as keys. Simple, fast, works fine. The mistake was not accounting for case sensitivity in the key lookup. Vercel's Edge Config get() function does an exact string match. Our legacy CMS had generated URLs with mixed case in a few categories (/Blog/Post-Title instead of /blog/post-title). The redirect rules I migrated were all lowercase. The incoming requests from external links and bookmarks were mixed case.
Result: approximately 800 URLs that should have 301-redirected were instead hitting the origin and returning 404s, because neither the redirect rule matched (wrong case) nor did the origin pages exist (they'd been migrated to new URLs). These 404s persisted for eleven days before I caught them in a GSC index coverage audit. In that time, several mid-authority pages dropped from positions 4-8 to positions 15-40.
The fix was a case-normalization step before the Edge Config lookup:
// Fix: normalize path case before Edge Config lookup
const normalizedPath = url.pathname.toLowerCase();
const target = redirectMap[normalizedPath];
Two lines. Eleven days to catch it. The rankings recovered over about six weeks, but it was a painful and entirely preventable mistake. I now run a post-migration redirect validation script that checks a random sample of 5,000 redirect rules on both the exact case and three common case variants before I consider any migration done.
What I'd Tell Myself in Early 2025
Before you pick a platform, measure where Googlebot actually comes from in your server logs. Not your users. Googlebot. The crawl origin geography often doesn't match your user geography, and the platform that performs best for your users may not be the platform that performs best for your crawl efficiency.
Run a CCE analysis before you demo any platform. Cloudflare's 310 pops will impress you in every demo. But if all your traffic and all your Googlebot activity is in US-East and Western Europe, those extra pops are irrelevant to your SEO outcomes.
Instrument everything from day one. Server-Timing headers for crawl correlation. Logpush or log streaming to BigQuery. TTFB synthetic monitoring from your specific target markets, not just US-East. The default dashboards on all three of these platforms are optimized to show you the good numbers. The SEO-relevant numbers require custom instrumentation.
And finally: the platform is not the product. I've seen teams spend four months optimizing their edge stack and shave 60ms off TTFB while leaving JavaScript that adds 3 seconds to LCP untouched. Edge compute is infrastructure. It enables performance but it doesn't replace it. Fix your rendering pipeline, fix your LCP element loading, fix your JavaScript bloat. Then edge compute takes you from good to excellent.
The math is worth doing. It's just not the only math.
FAQ
Does Vercel's edge network actually improve Googlebot crawl efficiency?
Yes, but primarily in US and Western European markets where Vercel has dense PoP coverage. For global sites with significant Googlebot activity in Asia, Africa, or Latin America, Cloudflare's broader PoP network produces meaningfully better TTFB for Googlebot requests, which correlates with improved crawl frequency in our log analysis data.
Is Cloudflare Workers cloaking if I treat Googlebot requests differently?
Not if you serve the same HTML content. Stripping analytics cookies from Googlebot responses, bypassing personalisation logic, or serving cached HTML instead of dynamically generated HTML are all performance optimizations, not cloaking. Cloaking means serving different content (different text, different links, different page structure) to bots versus users. Cache optimization is explicitly acceptable per Google's documentation.
What is Fastly Compute@Edge and how does it differ from Cloudflare Workers?
Both are edge compute platforms that run code at CDN nodes globally. Fastly uses a WebAssembly runtime, which means you can compile Rust or Go to Wasm for near-native performance. Cloudflare Workers use V8 isolates (same engine as Chrome), which offer near-zero cold start times. For SEO purposes, the meaningful differences are network coverage (Cloudflare wins), developer experience (Cloudflare wins), APAC performance (Fastly is competitive or better), and pricing at high request volumes (Fastly is often cheapest).
How much does TTFB actually affect Google rankings in 2026?
TTFB's direct ranking effect is through Core Web Vitals (LCP) and crawl budget efficiency. For LCP, the relationship is close to 1:1 when the LCP element is in the initial HTML payload, and close to 0 when it's client-rendered or lazy-loaded. For crawl efficiency, our data from Project Skein showed a 2.3x improvement in crawl frequency for the top 500k URLs after reducing Googlebot TTFB from ~380ms to ~71ms. Both effects are real but context-dependent.
Can I use Fastly Compute@Edge with a Next.js application?
Not natively. Fastly does not have a Next.js integration equivalent to Vercel's first-class support or Cloudflare's OpenNext adapter. You would typically use Fastly as a CDN and edge compute layer in front of a Next.js application hosted elsewhere (a VPS, GCP, or similar), handling redirect logic, cache optimization, and bot handling at the Fastly layer while the Next.js application runs on the origin. This is more complex than the Vercel or Cloudflare approaches but viable for organizations that need Fastly's specific performance or compliance characteristics.
