31. Edge Computing & CDN
Edge Computing & CDN
TL;DR
- CloudFront Functions, Lambda@Edge, and Global Accelerator sit on a spectrum of capability versus overhead — picking the heaviest option “to be safe” costs real latency for logic that didn’t need it.
- CloudFront caches content at edge locations; the highest-severity, most common misconfiguration is a cache key that doesn’t account for personalization, which leaks one user’s response to another.
- CloudFront Functions: sub-millisecond, lightweight JS, viewer-request/response manipulation only. Lambda@Edge: fuller runtime, network calls, request-body access, higher overhead.
- Global Accelerator solves routing, not caching — static anycast IPs over AWS’s private backbone, used for non-HTTP protocols or static-entry-point requirements.
- Cache invalidation is not instantaneous everywhere and has real cost at scale — prefer versioned/cache-busting URLs for routine deploys; reserve invalidation for emergencies.
Core Concepts
CloudFront and cache key configuration
CloudFront is the CDN foundation — caching content at edge locations close to users, reducing both latency and origin load for anything cacheable. The design decision that matters most, and the one that causes real incidents when missed, is cache key configuration. Caching a response that should be personalized per user, without the cache policy accounting for what makes it personal (an auth header, a session cookie), serves one user’s cached response to another. This surfaces most often when personalization is added to a previously-generic cached endpoint without revisiting the cache policy.
CloudFront Functions
Run in a lightweight JavaScript runtime directly at the edge, purpose-built for high-volume, simple viewer-request/response manipulation — header rewrites, basic redirects, simple auth checks — with sub-millisecond execution overhead. This is the right default for simple logic at scale.
Lambda@Edge
The heavier option: a fuller Node.js/Python runtime, longer execution time allowances, and the ability to make network calls or access the request body. Necessary when edge logic needs capabilities CloudFront Functions doesn’t support, at the cost of meaningfully more overhead and latency per invocation. Defaulting to Lambda@Edge for logic CloudFront Functions would handle is unnecessary cost and latency; defaulting to CloudFront Functions for logic that genuinely needs Lambda@Edge’s capabilities means the implementation won’t work at all.
Global Accelerator
Solves a different problem than either edge-compute option: not content caching, but optimized network routing via static anycast IP addresses over AWS’s private backbone. This is the right tool for non-HTTP protocols (raw TCP/UDP for gaming, IoT), or when a static entry point and the fastest possible routing to the nearest healthy endpoint matters more than content caching.
Cache invalidation
Not instantaneous across every edge location, and it has real cost at meaningful scale. The better default for content that changes on every deployment is versioned object keys or cache-busting query strings — a new URL for a new version naturally bypasses stale cache without invalidating anything. Reserve explicit invalidation calls for genuine emergencies rather than baking them into every routine release pipeline.
CloudFront Functions vs Lambda@Edge vs Global Accelerator
| Aspect | CloudFront Functions | Lambda@Edge | Global Accelerator |
|---|---|---|---|
| Problem solved | Lightweight viewer request/response edits | Heavier edge compute needing full runtime | Network routing, not caching |
| Runtime | Minimal JS at edge | Fuller Node.js/Python | N/A — routing layer |
| Execution overhead | Sub-millisecond | Higher, meaningfully more latency | N/A |
| Capabilities | Header rewrites, redirects, simple checks | Network calls, request body access, longer execution | Static anycast IPs, private backbone routing |
| Best fit | High-volume simple logic | Genuinely heavier logic | Non-HTTP protocols, static entry points |
Common Pitfalls
- Pitfall: Caching a personalized API response without a cache key that accounts for personalization. Why: The cache policy doesn’t vary on the factor (auth header, session cookie) that makes the response unique per user. Fix: Configure the cache key/policy to include the personalization factor, or disable caching for that response.
- Pitfall: Defaulting to Lambda@Edge for simple logic. Why: CloudFront Functions would handle the same logic with far less latency overhead. Fix: Reserve Lambda@Edge for logic that genuinely needs network calls, request-body access, or a fuller runtime.
- Pitfall: Relying on explicit cache invalidation as a routine deployment step. Why: Invalidation is not instantaneous everywhere and has real cost at scale. Fix: Adopt versioned cache-busting URLs for routine deploys; reserve invalidation for genuine incidents.
- Pitfall: Trying to force non-HTTP or ultra-low-latency static-IP requirements through CloudFront. Why: CloudFront is built for HTTP content caching, not raw TCP/UDP routing. Fix: Use Global Accelerator for non-HTTP protocols or static-entry-point requirements.
Interview Questions
- “A CDN starts serving one logged-in user’s dashboard data to a different user. Walk me through your investigation and the fix.” — tests whether cache key misconfiguration is the immediate, correct hypothesis.
- “When would you choose Lambda@Edge over CloudFront Functions, and what does that choice cost you?” — tests understanding of the capability/overhead trade-off, not just familiarity with both names.
- “Design global ingress for a real-time multiplayer game needing the lowest possible UDP latency with a static IP for firewall allow-listing.” — tests whether Global Accelerator is correctly reached for over CloudFront.
- “Why shouldn’t cache invalidation be part of every deployment pipeline?” — tests understanding of invalidation cost and propagation delay versus versioned cache-busting.