Edge computing patterns: compute at PoPs (Cloudflare Workers V8 isolates, Vercel Edge, Lambda@Edge, Fastly Compute@Edge WASM, Deno Deploy). Three scenarios: edge auth (verify JWT before forwarding), A/B routing with sticky cookie, image resize on demand. Three ADRs cover edge-vs-origin compute, V8 isolates vs WASM vs containers, and KV at edge vs origin DB.
Пользователь в Берлине стучится в твоё API в us-east-1. RTT через океан — ~150ms в одну сторону. Просто TLS-handshake съест половину секунды. Если этому пользователю нужно сделать 3 запроса подряд — он уже потерял 1.5 секунды на воздух, на котором ты ничего полезного не посчитал.
Edge computing решает это перетаскиванием кода (не только статики) на 250+ PoP по всему миру: Cloudflare Workers, Vercel Edge Functions, Fastly Compute@Edge, AWS Lambda@Edge, Deno Deploy. Берлинский пользователь попадает в франкфуртский PoP за 5-10ms. Если worker может ответить локально (auth check, A/B-bucket, image transform, geo-redirect, кеш-хит) — origin вообще не услышит о запросе.
Цена: ограниченный рантайм (V8-изолят без Node API, 50ms-30s CPU, 128MB RAM, KV вместо настоящей БД) и стоимость инвокаций в 2-5x от обычной Lambda. Платишь, чтобы свернуть цепочку межконтинентальных RTT в один локальный хит.
Три места, где может жить код:
Состояние тоже трёхуровневое:
Главное правило: код на edge, если может ответить из заголовков + KV-лукапа за <50ms CPU. Всё остальное forward'ится на origin одним подготовленным sub-request'ом.
us-east-1: LB, Node-монолит, Postgres, S3.Edges:
ADR на ноде anycast-ip разбирают три ключевых решения: edge vs origin, выбор рантайма (V8 / WASM / Firecracker), KV vs origin DB.
JWT-верификация на PoP. Worker фетчит JWKS из локального KV (~1ms), верифицирует подпись через crypto.subtle.verify, проверяет exp/aud. Хороший токен — форвард на origin с заголовком X-User-Id: u_42 (origin доверяет, потому что единственный путь внутрь — через edge). Плохой токен — 401 за ~10ms, origin вообще не видит запрос. На 1M атак в день экономит ~39 origin-CPU-часов бесполезной работы.
A/B routing на edge. Worker читает конфиг эксперимента из KV, хеширует user_id mod 100, выбирает variant, ставит Set-Cookie: ab-bucket=B Max-Age=2592000. Повторные визиты читают cookie — 0 KV-операций. Форвардит на origin с X-AB-Bucket: B. Origin не знает про SDK эксперимента, просто видит чистый трафик A или B. Когда PM меняет конфиг 50/50 → 70/30, origin пишет в kv-master, и все PoP получают новое значение за ~60s.
Image resize on demand. Tokyo-пользователь запрашивает /img/avatars/u_42.jpg?w=200&h=200. Cache miss → worker фетчит оригинал из S3 (150ms cross-pacific, один раз), отдаёт байты в WASM-libvips, ресайзит 200×200 + reencode WebP (~30ms CPU), кладёт в cache с edge_ttl=1y. Второй пользователь из Tokyo — cache hit за ~5ms. Берлинский пользователь хочет тот же URL — EU PoP платит свою отдельную миссию в S3 (каждый PoP независимый). Итого: origin платит ровно N раз, где N — число PoP, которые когда-либо отдали этот URL. При 300 PoP и 1M req/day равномерно S3 видит ~300 запросов, не 1M.
ADR-001: edge vs origin compute. Edge, если CPU <50ms, решение из headers+KV, и экономия origin-RTT существенно режет p99 (auth, A/B, geo-redirect, image resize, header rewrite, bot detection, лёгкие JSON API). Origin — для тяжёлой обработки (PDF, видео, ML >100ms), всего что хочет реляционную БД с pool, всего что просит >128MB RAM или Node-only либу. Гибрид — реалистичный паттерн: edge делает auth/routing/personalization, потом forward'ит на origin сокращённый запрос. Анти-паттерн: лифт-энд-шифт Node-монолита на edge — словишь fs is not defined за минуты. Анти-паттерн: дёргать Postgres в us-east-1 из Tokyo edge — заплатил Tokyo→Virginia RTT внутри edge handler, обнулил весь смысл.
ADR-002: V8 isolates vs WASM vs containers. V8 isolates (Cloudflare, Vercel, Deno Deploy) — cold-start ~5ms, JS/TS only, security boundary = V8 сам. WASM (Fastly Compute@Edge) — cold-start ~1ms, полиглот (Rust, Go, AssemblyScript, JS-on-SpiderMonkey-on-WASM), более сильная изоляция (sandbox + process). Containers (Lambda@Edge на Firecracker) — cold-start 100ms-1s, полный Node-эко, больше лимиты. Решение: JS-heavy + минимальный cold start → Cloudflare Workers. Смешанные языки или сильная изоляция критична → Fastly. Глубоко в AWS, нужен полный Node, ок с 100ms+ хвостом → Lambda@Edge (плюс CloudFront Functions для тривиальных header rewrite'ов). Уже на Vercel под Next.js → Vercel Edge (под капотом Cloudflare runtime). Доминирующий драйвер стоимости — egress, не количество инвокаций.
ADR-003: KV vs regional edge DB vs origin DB. Read-mostly конфиг, который нужен всем PoP, и staleness ~60s ок → KV. Per-user mutable state с read-your-writes (сессия, корзина, score) → regional edge DB (Durable Objects, D1, Turso). Транзакционное, JOIN на 3+ таблицы, всё где stale read = испорченные деньги → origin DB (одним prepared sub-request'ом). Две ловушки: (1) использовать KV как БД — writes медленные, транзакций нет, словишь lost-update; (2) открыть Postgres TCP-connection с edge — connections дорогие, edge будет спавнить много короткоживущих, БД исчерпает слоты за час под нагрузкой. Решение: HTTP-based serverless драйверы (Neon, Supabase, PgBouncer в transaction mode) или explicit gateway в origin-регионе.
export const runtime = 'edge'), Edge Config для KV.user_id из JWT или device-id из cookie.fs, child_process, нативные модули, pool'ы — ничего не работает. Edge-код пишут с нуля под edge-рантайм.us-east-1, ты только что заплатил межконтинентальный RTT внутри handler'а. Либо реплика рядом, либо forward на origin.?w=4097&h=4097 или произвольные значения раздуют cache-key space и съедят CPU-бюджет. Жёсткий white-list (200/400/800/1600).