Edge compute matured. The hype peaked, the patterns settled. By 2026 the question isn’t “edge or not” but “what part of my system fits at the edge.” This post is the honest take.

What edge means

Code running at hundreds of POPs (points of presence) instead of one or a few regions. Request hits the nearest POP; runs there; latency drops to ms.

[User in Tokyo] ──5ms──▶ [Edge POP Tokyo]
                              ↓ (only if needed)
                         [Origin region]

Where edge wins

  • Cache + cache logic (set headers, vary keys).
  • Auth at edge (validate JWT, reject unauthorized).
  • Bot mitigation / rate limiting close to users.
  • A/B testing / feature flags without origin round-trip.
  • Routing (region selection, BFF logic).
  • Image / video transformations.
  • Public read APIs with global audience.
  • Webhook receivers (handle, queue, ack fast).

Where edge doesn’t win

  • Heavy DB queries — DB is in one region; edge → DB still has full RTT.
  • Stateful sessions — state lives somewhere central anyway.
  • Long-running compute — edge platforms have CPU time limits.
  • Large dependencies — edge runtimes have package limits.

Platforms

StrengthsLimits
Cloudflare WorkersV8 isolates; <5ms cold start; cheapest50ms CPU (paid: more); 128MB memory
Vercel EdgeNext.js integration; familiarVercel-locked; depends on CF underneath
Deno DeployStandards-based; clean DXSmaller ecosystem
AWS Lambda@EdgeAWS-integrated; Node + PythonCold starts; tighter limits than Lambda
Fastly ComputeWASM; performantFewer features; learning curve

For most: Cloudflare Workers + Vercel for Next-shaped apps.

Cloudflare Workers basics

export default {
    async fetch(request, env, ctx) {
        const url = new URL(request.url);
        if (url.pathname === "/api/health") {
            return Response.json({ ok: true });
        }
        return fetch(request);  // proxy to origin
    }
};

Deploy:

wrangler deploy

Sub-5ms cold start; runs at every Cloudflare POP.

Edge data: KV / D1 / R2 / Durable Objects

Cloudflare’s edge-native data:

  • KV: eventually-consistent global key-value. Good for config, caches.
  • D1: SQLite at the edge; strong-consistent within region; replicas across.
  • R2: S3-compatible object storage; zero egress.
  • Durable Objects: stateful, single-instance per ID. Good for coordination, presence.
const cached = await env.KV.get("config");
const user = await env.D1.prepare("SELECT * FROM users WHERE id = ?")
    .bind(userId).first();

Hono on the edge

import { Hono } from "hono";

const app = new Hono();

app.get("/api/me", async (c) => {
    const token = c.req.header("authorization");
    const user = await verify(token);
    return c.json({ user });
});

export default app;

See Hono on Cloudflare Workers . Tiny framework; fits edge constraints.

Database at the edge: hard

Most DBs are in one region. Edge → DB still has full latency.

Solutions:

  • Read-only data: replicate to D1 / Turso / Neon read replicas; edge reads.
  • Writes: send to origin region; edge is read-mostly.
  • CDN cache in front of origin DB queries.

Rule of thumb: edge serves cached / static / pre-computed data; origin handles state.

Data locality patterns

[User] ──▶ [Edge: cached + static + auth check]
                                    ↓ (cache miss)
                             [Origin: DB-backed reads]
                             [DB: regional]

Edge handles 90% of traffic from cache. Origin handles 10% of cache misses.

For a CDN-friendly product: edge cache hit rate of 90%+ is normal.

Auth at the edge

app.use("*", async (c, next) => {
    const token = c.req.header("authorization");
    if (!token) return c.json({ error: "unauthorized" }, 401);
    const user = await verifyJWT(token, env.JWT_SECRET);
    if (!user) return c.json({ error: "invalid token" }, 401);
    c.set("user", user);
    await next();
});

JWT verification is local CPU; doesn’t need origin. Reject early; protect origin.

Limits to plan for

Cloudflare Workers (paid):

  • CPU time: 50ms default; up to 5min for paid plans.
  • Subrequests: 50 per invocation default; 1000 paid.
  • Memory: 128MB.
  • Code size: ~3MB.

For heavy work: hit these. Move that part to origin.

Cold start reality

PlatformCold start
Cloudflare Workers1-5ms (V8 isolates, always warm)
Vercel Edge (CF underneath)1-5ms
AWS Lambda@Edge50-200ms
Deno Deploy10-30ms

Workers’ isolate model is the gold standard. AWS catches up slowly with SnapStart.

Observability

Edge logs go to:

  • Cloudflare Workers Logs (built-in; basic).
  • Tail logs (Wrangler).
  • Workers Trace Events → external (Logflare, Honeycomb, etc.).
  • OpenTelemetry via OTel collector somewhere.

Tracing across edge → origin → DB needs propagation: pass traceparent headers explicitly.

Common mistakes

1. Lift-and-shift

Move whole Express app to edge; hits CPU limit; unhappy. Edge is for specific patterns.

2. DB in distant region

Edge → us-east DB from Tokyo: 200ms RTT. Slower than running everything in Tokyo region.

3. No cache strategy

Edge code runs every request; doesn’t cache responses. Use Cache API + Cache-Control.

4. Heavy deps

Including a 5MB SDK; deployment fails. Audit bundle size.

5. Coupled edge + origin

Edge code calls origin; origin needs edge to deploy. Decouple; deploy independently.

What I’d ship today

For a global app:

  • Edge: routing, auth check, cache, A/B, bot defense.
  • Origin (one region): DB, business logic, async jobs.
  • Static assets at edge (R2 / Vercel Blob).
  • Read replicas at edge for reads (D1 / Turso) when warranted.
  • Hono / Vercel Edge Functions as the runtime.

Don’t aim for “all edge.” Hybrid wins.

Read this next

If you want my edge-first reference architecture (Hono + D1 + R2), it’s at rajpoot.dev .


Building something AI-, backend-, or data-heavy and want a second pair of eyes? I do consulting and freelance work — see my projects and ways to reach me at rajpoot.dev .