Edge Functions: When and Why to Use Them
Edge Functions: When and Why to Use Them
Edge functions run your server-side code in data centers close to your users — not in a single region, but distributed globally. They start in milliseconds, cost per invocation, and excel at latency-sensitive tasks.
What Are Edge Functions?
Traditional servers run in one region (e.g., us-east-1). When a user in Tokyo makes a request, it travels across the Pacific and back. Edge functions run in 200+ locations worldwide, so the same request hits a data center in Tokyo.
Major Platforms
Vercel Edge Functions
Built into Next.js with the Edge Runtime:
// app/api/geo/route.ts
export const runtime = "edge";
export async function GET(request: Request) {
const country = request.headers.get("x-vercel-ip-country") ?? "unknown";
const city = request.headers.get("x-vercel-ip-city") ?? "unknown";
return Response.json({
message: Hello from \${city}, \${country}!,
timestamp: Date.now(),
});
}
Cloudflare Workers
Full-featured edge runtime with KV storage, Durable Objects, and D1 databases:
export default {
async fetch(request: Request, env: Env): Promise {
const url = new URL(request.url);
// Read from KV at the edge
const cached = await env.CACHE.get(url.pathname);
if (cached) return new Response(cached, {
headers: { "Content-Type": "application/json" },
});
const data = await fetchFromOrigin(url.pathname);
await env.CACHE.put(url.pathname, JSON.stringify(data), { expirationTtl: 60 });
return Response.json(data);
},
};
Deno Deploy
Uses standard Web APIs and Deno runtime:
Deno.serve(async (request: Request) => {
const url = new URL(request.url);
if (url.pathname === "/api/time") {
return Response.json({
utc: new Date().toISOString(),
region: Deno.env.get("DENO_REGION"),
});
}
return new Response("Not found", { status: 404 });
});
When to Use Edge Functions
Great For
Not Great For
fs, limited crypto, no native modules.Middleware Pattern
Use edge functions as middleware to intercept requests before they reach your application:
// middleware.ts (Next.js)
import { NextResponse } from "next/server";
import type { NextRequest } from "next/server";
export function middleware(request: NextRequest) {
// Block specific countries
const country = request.geo?.country;
if (country === "XX") {
return new NextResponse("Not available in your region", { status: 451 });
}
// Add security headers
const response = NextResponse.next();
response.headers.set("X-Frame-Options", "DENY");
response.headers.set("X-Content-Type-Options", "nosniff");
return response;
}
export const config = {
matcher: ["/api/:path*", "/app/:path*"],
};
Conclusion
Edge functions are ideal for latency-sensitive, lightweight operations — auth checks, redirects, personalization, and API proxying. They are not a replacement for your backend but a complement that handles the request lifecycle closer to your users.