Our Pick Cloudflare Workers — Larger global network, more powerful runtime, better pricing for compute-intensive workloads, and a complete edge platform with KV, R2, D1, and Durable Objects.
Cloudflare Workers vs Vercel Edge Functions

import ComparisonTable from ’../../components/ComparisonTable.astro’;

Edge functions run your code in data centers geographically close to users — minimizing latency without managing servers. Cloudflare Workers and Vercel Edge Functions are the two dominant platforms, but they serve different primary use cases.

Quick Verdict

Choose Cloudflare Workers if: You’re building standalone edge APIs, need the global network reach, want full-featured edge storage (KV, R2, D1), or have compute-intensive edge workloads.

Choose Vercel Edge Functions if: Your primary deployment is a Next.js application and you want middleware, A/B testing, or personalization with minimal configuration.


Feature Comparison

<ComparisonTable headers={[“Feature”, “Cloudflare Workers”, “Vercel Edge Functions”]} rows={[ [“Runtime”, “V8 isolates (Workers runtime)”, “V8 isolates (Edge Runtime)”], [“Global PoPs”, “300+”, “~100”], [“Cold start”, “~0ms (isolates)”, “~0ms (isolates)”], [“CPU time limit”, “50ms (free), 30s (paid)”, “1s”], [“Memory limit”, “128MB”, “128MB”], [“Request size”, “100MB body”, “4MB body”], [“Free tier”, “100K requests/day”, “500K requests/month (shared)”], [“Storage”, “KV, R2, D1, Durable Objects”, “Vercel KV (Redis), Blob”], [“WebSockets”, “Durable Objects”, “Limited”], [“Cron jobs”, “Workers Cron Triggers”, “Not native”], [“Framework integration”, “Framework-agnostic”, “Deep Next.js integration”], ]} />


Runtime Environment

Both use V8 isolates — the same engine as Chrome — instead of Node.js containers. This means:

  • Near-zero cold starts (microseconds vs. 100ms+ for Lambda)
  • No Node.js APIs (no fs, limited crypto, no native modules)
  • Web standard APIs (fetch, URL, Response, crypto.subtle)

What you can use:

// Both Cloudflare Workers and Vercel Edge Functions support:
// Web Fetch API, URL, Headers, Request, Response
// TextEncoder/TextDecoder
// crypto.subtle (Web Crypto)
// Streams API
// AbortController

// What you CANNOT use:
// fs (no file system)
// child_process
// Most npm packages that require Node.js internals
// Anything that needs a persistent TCP connection

Cloudflare Workers

Basic Worker:

// worker.ts
export default {
  async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> {
    const url = new URL(request.url);
    
    if (url.pathname === '/api/hello') {
      return Response.json({ 
        message: 'Hello from the edge!',
        location: request.cf?.city ?? 'unknown',
        country: request.cf?.country ?? 'unknown',
      });
    }
    
    return new Response('Not Found', { status: 404 });
  },
} satisfies ExportedHandler<Env>;

interface Env {
  MY_KV: KVNamespace;
  MY_DB: D1Database;
}

Cloudflare KV — distributed key-value storage:

export default {
  async fetch(request: Request, env: Env): Promise<Response> {
    const cache_key = new URL(request.url).pathname;
    
    // Try cache first
    const cached = await env.MY_KV.get(cache_key, 'json');
    if (cached) {
      return Response.json(cached, {
        headers: { 'X-Cache': 'HIT' }
      });
    }
    
    // Fetch from origin
    const data = await fetchFromDatabase(env);
    
    // Cache for 5 minutes
    await env.MY_KV.put(cache_key, JSON.stringify(data), {
      expirationTtl: 300
    });
    
    return Response.json(data, {
      headers: { 'X-Cache': 'MISS' }
    });
  }
}

Cloudflare D1 — SQLite at the edge:

export default {
  async fetch(request: Request, env: Env): Promise<Response> {
    if (request.method === 'GET') {
      const { results } = await env.DB.prepare(
        'SELECT * FROM products WHERE active = 1 LIMIT 20'
      ).all();
      
      return Response.json(results);
    }
    
    if (request.method === 'POST') {
      const body = await request.json<{ name: string; price: number }>();
      
      await env.DB.prepare(
        'INSERT INTO products (name, price) VALUES (?, ?)'
      ).bind(body.name, body.price).run();
      
      return Response.json({ success: true }, { status: 201 });
    }
    
    return new Response('Method Not Allowed', { status: 405 });
  }
}

Durable Objects — stateful edge (unique to Cloudflare):

// Persistent state, consistent globally — no other edge platform has this
export class Counter {
  state: DurableObjectState;
  
  constructor(state: DurableObjectState) {
    this.state = state;
  }
  
  async fetch(request: Request): Promise<Response> {
    let value = await this.state.storage.get<number>('value') ?? 0;
    
    if (request.method === 'POST') {
      value++;
      await this.state.storage.put('value', value);
    }
    
    return Response.json({ value });
  }
}

Use cases for Durable Objects: real-time collaboration, rate limiting with precision, game state, live counters.


Vercel Edge Functions

Next.js Middleware (most common use case):

// middleware.ts — runs on every request before routing
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';

export function middleware(request: NextRequest) {
  const { pathname } = request.nextUrl;
  
  // A/B testing — split traffic
  const bucket = Math.random() > 0.5 ? 'a' : 'b';
  const response = NextResponse.next();
  response.cookies.set('ab-bucket', bucket);
  
  // Geolocation-based redirect
  const country = request.geo?.country;
  if (country === 'DE' && !pathname.startsWith('/de')) {
    return NextResponse.redirect(new URL(`/de${pathname}`, request.url));
  }
  
  // Auth check
  const token = request.cookies.get('auth-token');
  if (pathname.startsWith('/dashboard') && !token) {
    return NextResponse.redirect(new URL('/login', request.url));
  }
  
  return response;
}

export const config = {
  matcher: ['/((?!_next/static|_next/image|favicon.ico).*)'],
};

Edge API Route in Next.js:

// app/api/fast/route.ts
import { NextRequest } from 'next/server';

export const runtime = 'edge'; // Declare edge runtime

export async function GET(request: NextRequest) {
  const geo = {
    city: request.geo?.city ?? 'unknown',
    country: request.geo?.country ?? 'unknown',
    region: request.geo?.region ?? 'unknown',
  };
  
  return Response.json({
    message: 'Edge response',
    location: geo,
    timestamp: Date.now(),
  });
}

Vercel KV (Redis at the edge):

import { kv } from '@vercel/kv';

export const runtime = 'edge';

export async function GET(request: Request) {
  const key = 'visitor-count';
  const count = await kv.incr(key);
  
  return Response.json({ visitors: count });
}

Pricing Comparison

MetricCloudflare Workers FreeCloudflare Workers PaidVercel Pro
Requests100K/day$0.30/million500K/month (shared)
CPU time10ms/request30s limit1s limit
KV reads100K/day$0.50/million$0.30/million
KV writes1K/day$5/million$2/million
Monthly baseFree$5/month$20/month

For API-heavy workloads (millions of requests), Cloudflare is significantly cheaper.


Performance at the Edge

Request latency by location (typical):

User LocationCloudflare WorkersVercel Edge
New York3ms5ms
London4ms6ms
Tokyo5ms8ms
São Paulo6ms12ms
Mumbai5ms15ms
Sydney5ms10ms

Cloudflare’s 300+ PoPs vs Vercel’s ~100 means better coverage in emerging markets and regions where Vercel has fewer data centers.


When to Choose Each

Choose Cloudflare Workers:

  • Building standalone edge APIs (not tied to Next.js)
  • Need D1, KV, R2 at the edge (persistent state)
  • Global audience — especially Asia, Latin America, Africa
  • Real-time applications (WebSockets via Durable Objects)
  • High-volume compute (Cloudflare’s pricing is better at scale)
  • Cron jobs and scheduled tasks

Choose Vercel Edge Functions:

  • Your app is Next.js-first and deployed on Vercel
  • Need middleware for auth, redirects, or feature flags
  • Team is already on Vercel platform
  • A/B testing and personalization for Next.js routes
  • Don’t need the full storage/compute platform

Bottom Line

Cloudflare Workers is the more capable edge computing platform — more PoPs, longer CPU time limits, complete storage ecosystem, and better economics at scale. Vercel Edge Functions wins when your primary concern is seamless Next.js integration with minimal configuration. For standalone edge APIs or new edge-native projects, Cloudflare Workers is the clear choice.