Edge Computing Basics Cheat Sheet
Introduces edge computing concepts, CDN vs edge compute, and common platforms like CloudFront Functions and Cloudflare Workers.
Core Concepts
Why and how edge computing differs from centralized cloud compute.
- Edge Computing- Processing data physically closer to where it's generated/consumed, reducing latency
- CDN (Content Delivery Network)- Distributed cache of static content served from geographically nearby nodes
- Edge Function- Small units of code executed at CDN points of presence, close to the user
- PoP (Point of Presence)- A physical edge location where servers cache content and run edge compute
- IoT Edge Gateway- Local device that aggregates/processes sensor data before sending to the cloud
Common Edge Platforms
Where edge functions typically run.
- Cloudflare Workers- V8-isolate-based JS/WASM runtime deployed to Cloudflare's global edge network
- AWS CloudFront Functions- Lightweight JS functions for viewer request/response manipulation at the CDN edge
- AWS Lambda@Edge- Full Lambda functions triggered by CloudFront events, more capability than CloudFront Functions
- Fastly Compute- WASM-based edge compute platform built on Fastly's CDN
- Vercel Edge Functions- Edge runtime for Next.js apps, deployed globally close to users
Cloudflare Worker Example
A minimal edge function that modifies a response header.
export default { async fetch(request) { const response = await fetch(request); const newResponse = new Response(response.body, response); newResponse.headers.set('X-Served-By', 'edge'); return newResponse; },};
Edge Runtime Constraints
Limits that shape what's actually feasible to run at the edge, beyond the basic 'stateless, low CPU time' framing.
- No Persistent Local Disk- Edge isolates are ephemeral; any state must go to an external store (KV, Durable Object, D1) or be lost between invocations
- Limited Runtime APIs- V8 isolate runtimes (Workers, Vercel Edge) lack Node APIs like `fs`, native modules, and long-lived TCP sockets in some cases
- Cold Start vs Warm Isolate- V8-isolate platforms start in single-digit milliseconds; container-based edge (Lambda@Edge with full runtime) can take hundreds of ms
- Geographic Data Residency- Requests may execute in a PoP outside the origin's compliance region unless the platform supports jurisdiction pinning (e.g. Cloudflare Regional Services)
- Cache-Key Cardinality- Personalizing responses at the edge (per-user, per-header) can explode cache hit rates to near zero if the cache key isn't scoped carefully
- Outbound Fetch Limits- Most edge platforms cap the number/duration of subrequests per invocation, so N+1 origin calls from an edge function are a real risk
Stateful Edge Compute with a Cloudflare Durable Object
A Durable Object provides strongly consistent, single-instance state at the edge — useful for rate limiting or a WebSocket coordination point where a stateless Worker can't help.
export class RateLimiter { constructor(state, env) { this.state = state; } async fetch(request) { const count = (await this.state.storage.get('count')) || 0; const windowStart = (await this.state.storage.get('windowStart')) || Date.now(); if (Date.now() - windowStart > 60_000) { await this.state.storage.put('windowStart', Date.now()); await this.state.storage.put('count', 1); return new Response('ok', { status: 200 }); } if (count >= 100) { return new Response('rate limited', { status: 429 }); } await this.state.storage.put('count', count + 1); return new Response('ok', { status: 200 }); }}// Worker routes each client to its own Durable Object instance by IDexport default { async fetch(request, env) { const id = env.RATE_LIMITER.idFromName(new URL(request.url).hostname); const stub = env.RATE_LIMITER.get(id); return stub.fetch(request); },};
Lambda@Edge: Geo-Based Origin Routing
An origin-request trigger that rewrites the origin based on the CloudFront-provided viewer country header, common for data-residency-aware edge routing.
exports.handler = async (event) => { const request = event.Records[0].cf.request; const headers = request.headers; const country = headers['cloudfront-viewer-country'] ? headers['cloudfront-viewer-country'][0].value : 'US'; const originsByRegion = { DE: 'eu-origin.example.com', FR: 'eu-origin.example.com', JP: 'apac-origin.example.com', }; const customOrigin = originsByRegion[country]; if (customOrigin) { request.origin.custom.domainName = customOrigin; headers['host'] = [{ key: 'Host', value: customOrigin }]; } return request;};
Edge Caching Strategies
Patterns for keeping edge-cached content both fast and correct.
- stale-while-revalidate- Serve the cached (possibly stale) response immediately while asynchronously refetching from origin to update the cache
- stale-if-error- Serve stale cached content if the origin errors out or times out, trading freshness for availability
- Cache Key Normalization- Strip irrelevant query params/headers before hashing the cache key so equivalent requests actually hit the same cache entry
- Tiered Caching- Regional edge caches sit between PoPs and origin, absorbing cross-PoP cache misses so origin only sees one request per region
- Soft Purge vs Hard Purge- Soft purge marks content stale (triggers SWR) instead of evicting it outright, avoiding a thundering herd on the origin
- Cache Tags / Surrogate Keys- Group many cached objects under one tag so a single purge call can invalidate everything related to, e.g., one product update
Working Around Edge/Database Connection Limits
Edge functions can spin up thousands of concurrent isolates, each needing its own DB connection — an HTTP-based pooler avoids exhausting the database's connection limit.
// Instead of a raw TCP driver (which many edge runtimes can't use anyway),// query through an HTTP-based pooler/proxy designed for edge concurrency.import { neon } from '@neondatabase/serverless';export default { async fetch(request, env) { const sql = neon(env.DATABASE_URL); // HTTP driver, no persistent socket const rows = await sql`SELECT id, name FROM products WHERE id = ${new URL(request.url).searchParams.get('id')}`; return new Response(JSON.stringify(rows), { headers: { 'content-type': 'application/json' }, }); },};
Edge runtimes are typically stateless and impose strict CPU-time limits (often tens of milliseconds) — keep edge functions to routing, header manipulation, or simple auth checks, and delegate heavier logic back to origin.