We ran the same handler—JSON in, JSON out—for 90 days across Vercel Edge, Cloudflare Workers, and Fastly Compute. Same region targets (Frankfurt + London), synthetic checks every five minutes, plus RUM samples on a client’s B2B portal.
What the P50 / P95 taught us
Cold starts still matter on edge if you deploy often. Cloudflare showed the tightest tail on our tiny handler; Fastly rewarded us when we pinned logic near existing origins. Vercel traded a hair more variance for developer speed we already valued on the same mono-repo.
We are not publishing a league table. Platforms change monthly. The surprise was how often DNS and auth handoffs dominated the diff—not the JavaScript runtime slogan.
Observability was the real bill
Unless you log origin round-trips and edge cache status together, you optimise the wrong layer. We wired OpenTelemetry-style trace IDs end to end for two weeks. Half the “edge slowness” was a misconfigured regional KV read.
Sample handler shape (trimmed)
export default {
async fetch(request) {
const t0 = Date.now();
const auth = await verifySession(request);
if (!auth.ok) return new Response('Unauthorized', { status: 401 });
const data = await fetchOriginJson(request, auth.context);
return jsonWithTiming(data, Date.now() - t0);
},
};
We kept handlers small. When the team wanted a full ORM at the edge, we pushed the work back to a Node region.
Where this breaks down
Long CPU work, large payloads, and laws that require processing in a fixed country. Edge is not physics-free.
Our read
Edge functions are a routing and latency tool, not magic. We adopt them when telemetry proves users hit cross-region pain, and when the team can operate the debug story. Otherwise a well-placed CDN and a fast origin still win.