What are Edge Functions?
Edge Functions are serverless functions that execute code at edge locations (CDN points of presence) closest to users. Compared to traditional serverless (like AWS Lambda), they achieve dramatically lower latency.
flowchart LR
subgraph Traditional["Traditional Serverless"]
User1["User<br/>(Tokyo)"] --> Region["Region<br/>(Virginia)"]
Region --> Response1["Response<br/>200ms"]
end
subgraph Edge["Edge Functions"]
User2["User<br/>(Tokyo)"] --> EdgeLoc["Edge<br/>(Tokyo)"]
EdgeLoc --> Response2["Response<br/>20ms"]
end
Major Platforms
1. Cloudflare Workers
One of the most mature edge platforms.
// Cloudflare Worker
export default {
async fetch(request: Request, env: Env): Promise<Response> {
const url = new URL(request.url);
// Cache check
const cache = caches.default;
let response = await cache.match(request);
if (!response) {
// Fetch from origin
response = await fetch(request);
// Store in cache
const responseToCache = response.clone();
responseToCache.headers.set('Cache-Control', 'max-age=3600');
await cache.put(request, responseToCache);
}
return response;
},
};
2. Vercel Edge Functions
Edge execution environment deeply integrated with Next.js.
// middleware.ts (Next.js)
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';
export function middleware(request: NextRequest) {
// Geo-based routing
const country = request.geo?.country || 'US';
if (country === 'JP') {
return NextResponse.rewrite(new URL('/jp', request.url));
}
// A/B testing
const bucket = Math.random() < 0.5 ? 'a' : 'b';
const response = NextResponse.next();
response.cookies.set('ab-test', bucket);
return response;
}
export const config = {
matcher: ['/((?!api|_next/static|favicon.ico).*)'],
};
3. Deno Deploy
Edge platform based on Deno runtime.
// main.ts (Deno Deploy)
Deno.serve(async (req: Request) => {
const url = new URL(req.url);
if (url.pathname === '/api/data') {
// Get data from KV store
const kv = await Deno.openKv();
const data = await kv.get(['cache', 'data']);
if (data.value) {
return Response.json(data.value);
}
// Generate and cache data
const newData = { timestamp: Date.now(), message: 'Hello from Edge!' };
await kv.set(['cache', 'data'], newData, { expireIn: 60000 });
return Response.json(newData);
}
return new Response('Not Found', { status: 404 });
});
4. AWS Lambda@Edge / CloudFront Functions
Edge execution environment integrated with AWS CDN.
// CloudFront Function
function handler(event) {
const request = event.request;
const headers = request.headers;
// Device detection
const userAgent = headers['user-agent']?.value || '';
const isMobile = /Mobile|Android/i.test(userAgent);
// Redirect to mobile URL
if (isMobile && !request.uri.startsWith('/m/')) {
return {
statusCode: 302,
headers: {
location: { value: `/m${request.uri}` },
},
};
}
return request;
}
Use Cases
1. Authentication & Authorization
// JWT token verification at the edge
async function verifyToken(request: Request): Promise<Response | null> {
const authHeader = request.headers.get('Authorization');
if (!authHeader?.startsWith('Bearer ')) {
return new Response('Unauthorized', { status: 401 });
}
const token = authHeader.slice(7);
try {
const payload = await verifyJWT(token, JWT_SECRET);
// Add user info to headers and forward to origin
const newRequest = new Request(request, {
headers: new Headers(request.headers),
});
newRequest.headers.set('X-User-ID', payload.sub);
return null; // Continue
} catch {
return new Response('Invalid Token', { status: 401 });
}
}
2. Personalization
// Content optimization based on geography and language
export default {
async fetch(request: Request): Promise<Response> {
const country = request.cf?.country || 'US';
const language = request.headers.get('Accept-Language')?.split(',')[0] || 'en';
// Region-specific pricing
const prices = {
US: { currency: 'USD', amount: 9.99 },
JP: { currency: 'JPY', amount: 980 },
EU: { currency: 'EUR', amount: 8.99 },
};
const price = prices[country] || prices['US'];
// Generate HTML at the edge
const html = `
<!DOCTYPE html>
<html lang="${language}">
<body>
<h1>Welcome!</h1>
<p>Price: ${price.currency} ${price.amount}</p>
</body>
</html>
`;
return new Response(html, {
headers: { 'Content-Type': 'text/html' },
});
},
};
3. API Gateway
// Rate limiting and routing
export default {
async fetch(request: Request, env: Env): Promise<Response> {
const ip = request.headers.get('CF-Connecting-IP') || 'unknown';
// Rate limiting (using Cloudflare Durable Objects)
const rateLimiter = env.RATE_LIMITER.get(env.RATE_LIMITER.idFromName(ip));
const { allowed } = await rateLimiter.fetch(request).then(r => r.json());
if (!allowed) {
return new Response('Too Many Requests', { status: 429 });
}
// Path-based routing
const url = new URL(request.url);
const routes = {
'/api/users': 'https://users-service.internal',
'/api/products': 'https://products-service.internal',
'/api/orders': 'https://orders-service.internal',
};
for (const [path, origin] of Object.entries(routes)) {
if (url.pathname.startsWith(path)) {
return fetch(new URL(url.pathname, origin), request);
}
}
return new Response('Not Found', { status: 404 });
},
};
4. Image Optimization
// Image resizing and format conversion
export default {
async fetch(request: Request): Promise<Response> {
const url = new URL(request.url);
const imageUrl = url.searchParams.get('url');
const width = parseInt(url.searchParams.get('w') || '800');
const format = url.searchParams.get('f') || 'webp';
if (!imageUrl) {
return new Response('Missing image URL', { status: 400 });
}
// Cloudflare Image Resizing
return fetch(imageUrl, {
cf: {
image: {
width,
format,
quality: 80,
},
},
});
},
};
Constraints and Optimization
Execution Time Limits
| Platform | CPU Time | Wall Time |
|---|---|---|
| Cloudflare Workers | 10ms-50ms | 30s |
| Vercel Edge | 25s | 25s |
| Deno Deploy | 50ms | Unlimited |
| Lambda@Edge | 5s | 30s |
Cold Start
// Best practices to minimize cold starts
// 1. Avoid initialization in global scope
// Bad
const heavyConfig = loadHeavyConfig(); // Runs every time
// Good
let cachedConfig: Config | null = null;
function getConfig(): Config {
if (!cachedConfig) {
cachedConfig = loadConfig();
}
return cachedConfig;
}
Memory Limits
// Save memory with streaming
export default {
async fetch(request: Request): Promise<Response> {
const response = await fetch('https://api.example.com/large-data');
// Stream transformation
const transformStream = new TransformStream({
transform(chunk, controller) {
// Process each chunk
const processed = processChunk(chunk);
controller.enqueue(processed);
},
});
return new Response(response.body?.pipeThrough(transformStream), {
headers: response.headers,
});
},
};
Platform Comparison
| Feature | Cloudflare Workers | Vercel Edge | Deno Deploy |
|---|---|---|---|
| Runtime | V8 Isolates | V8 Isolates | Deno |
| Global PoPs | 300+ | 100+ | 35+ |
| KV Store | ◎ Workers KV | ○ Edge Config | ◎ Deno KV |
| Database | ◎ D1 (SQLite) | ○ Postgres | ○ KV |
| Free Tier | 100k req/day | 100k req/mo | 100k req/day |
Related Articles
- CDN - Content Delivery Networks
- Serverless - Serverless Architecture
- Rate Limiting - API Protection
Summary
Edge Functions are a powerful tool for building globally low-latency applications.
- Low Latency: Execute closest to users
- Global Distribution: Automatically deployed worldwide
- Cost Efficient: Usage-based billing
- Simple Deployment: Reflect changes instantly with git push
Choose appropriate use cases like authentication, personalization, and API gateways to leverage edge computing effectively.
← Back to list