Edge computing brings computation closer to users, dramatically reducing latency. Combined with serverless, it enables globally distributed applications without managing infrastructure. At ZIRA Software, edge deployment reduced our global latency by 70%.
Edge vs Traditional Architecture
Traditional (Single Region)
User (Tokyo) → CDN → Origin (US-East) → Database
Latency: 200-400ms
Edge Computing
User (Tokyo) → Edge (Tokyo) → Regional Cache/DB
Latency: 20-50ms
Cloudflare Workers
// workers/api.ts
export default {
async fetch(request: Request, env: Env): Promise<Response> {
const url = new URL(request.url);
// Route handling at the edge
if (url.pathname.startsWith('/api/products')) {
return handleProducts(request, env);
}
if (url.pathname.startsWith('/api/user')) {
return handleUser(request, env);
}
return new Response('Not Found', { status: 404 });
},
};
async function handleProducts(request: Request, env: Env): Promise<Response> {
// Check edge cache first
const cache = caches.default;
const cacheKey = new Request(request.url, request);
let response = await cache.match(cacheKey);
if (!response) {
// Fetch from D1 database (edge SQLite)
const products = await env.DB.prepare(
'SELECT * FROM products WHERE active = 1 LIMIT 100'
).all();
response = new Response(JSON.stringify(products.results), {
headers: {
'Content-Type': 'application/json',
'Cache-Control': 'public, max-age=60',
},
});
// Store in edge cache
await cache.put(cacheKey, response.clone());
}
return response;
}
Vercel Edge Functions
// app/api/geo/route.ts
import { NextRequest } from 'next/server';
export const runtime = 'edge';
export async function GET(request: NextRequest) {
const geo = request.geo;
// Personalize based on location
const content = await getLocalizedContent(geo?.country || 'US');
return Response.json({
country: geo?.country,
city: geo?.city,
content,
});
}
// Middleware runs at the edge
// middleware.ts
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';
export function middleware(request: NextRequest) {
const country = request.geo?.country || 'US';
// Redirect to localized version
if (country === 'DE' && !request.nextUrl.pathname.startsWith('/de')) {
return NextResponse.redirect(new URL('/de' + request.nextUrl.pathname, request.url));
}
return NextResponse.next();
}
export const config = {
matcher: ['/((?!api|_next/static|favicon.ico).*)'],
};
AWS Lambda with Edge
// Lambda@Edge for CloudFront
import { CloudFrontRequestEvent, CloudFrontRequestResult } from 'aws-lambda';
export const handler = async (
event: CloudFrontRequestEvent
): Promise<CloudFrontRequestResult> => {
const request = event.Records[0].cf.request;
const headers = request.headers;
// A/B testing at the edge
const experimentCookie = headers.cookie?.find(c =>
c.value.includes('experiment=')
);
if (!experimentCookie) {
// Assign user to experiment group
const group = Math.random() < 0.5 ? 'A' : 'B';
request.headers['x-experiment-group']= [{ value: group }];
}
// Geo-based routing
const country= headers['cloudfront-viewer-country']?.[0]?.value;
if (country= 'CN') {
request.origin= {
custom: {
domainName: 'origin-cn.example.com',
port: 443,
protocol: 'https',
},
};
}
return request;
};
Edge Databases
// Cloudflare D1 (Edge SQLite)
const result = await env.DB.prepare(`
SELECT p.*, c.name as category_name
FROM products p
JOIN categories c ON p.category_id = c.id
WHERE p.active = 1
ORDER BY p.created_at DESC
LIMIT ?
`).bind(20).all();
// Turso (Distributed SQLite)
import { createClient } from '@libsql/client';
const client = createClient({
url: process.env.TURSO_DATABASE_URL,
authToken: process.env.TURSO_AUTH_TOKEN,
});
const result = await client.execute({
sql: 'SELECT * FROM users WHERE id = ?',
args: [userId],
});
// PlanetScale (Edge-compatible MySQL)
import { connect } from '@planetscale/database';
const conn = connect({
host: process.env.DATABASE_HOST,
username: process.env.DATABASE_USERNAME,
password: process.env.DATABASE_PASSWORD,
});
const results = await conn.execute('SELECT * FROM products');
Edge KV Storage
// Cloudflare KV
async function getSession(sessionId: string, env: Env): Promise<Session | null> {
const data = await env.SESSIONS.get(sessionId, 'json');
return data as Session | null;
}
async function setSession(session: Session, env: Env): Promise<void> {
await env.SESSIONS.put(session.id, JSON.stringify(session), {
expirationTtl: 86400, // 24 hours
});
}
// Vercel KV (Redis-compatible)
import { kv } from '@vercel/kv';
await kv.set('user:123', { name: 'John', visits: 1 });
const user = await kv.get('user:123');
await kv.incr('pageviews');
Cost Comparison
Monthly cost for 10M requests:
Traditional Server (EC2 + Load Balancer)
├── Always running: ~$150/month
└── Scales manually
Serverless (Lambda)
├── Pay per invocation: ~$20/month
├── Auto-scales
└── Cold starts possible
Edge (Cloudflare Workers)
├── First 10M free
├── Then $0.50/million
├── No cold starts
└── Global by default
Conclusion
Edge computing with serverless creates fast, globally distributed applications. Choose Cloudflare Workers for pure edge, Vercel for Next.js, or Lambda@Edge for AWS ecosystems.
Need edge deployment? Contact ZIRA Software for cloud architecture consulting.