How Fastly's Edge Network Handles HTTP Traffic: Fastly Architecture: Routing and Executing
- Length
- 3376 words
- Read
- 15 min
Key takeaways
- Anycast BGP steers inbound HTTP requests to the network‑nearest Fastly POP, not necessarily the network-nearest one.
- WebAssembly‑based compute runs inside the edge before the cache lookup, eliminating the heavyweight container stack that traditional edge serverless platforms use.
- Modified Varnish provides line‑rate caching with custom eviction and object‑lifecycle logic tuned for high‑throughput HTTP workloads.
- The combination of routing, WASM compute, and Varnish yields a deterministic request path that can sustain line‑rate traffic while keeping latency low enough for real‑time web experiences.
Research basis
All observations are drawn from Fastly’s public engineering blog posts, the Fastly developer documentation, and the Fastly “Edge Compute” whitepaper. Where the source does not disclose a numeric metric, I note the omission rather than guess.
The problem: delivering line‑rate HTTP at global scale
Fastly’s customers—media sites, e‑commerce platforms, and API providers—need to serve billions of HTTP requests per day with sub‑second latency. Traditional CDN designs that rely on static caching and occasional origin fetches struggle when the workload requires dynamic compute at the edge (e.g., personalization, A/B testing, security checks). Adding a full container runtime for each request would introduce tens of milliseconds of overhead, breaking the line‑rate guarantees that Fastly promises to its enterprise customers.
Why scale matters for Fastly’s business
Fastly advertises a network of overmany POPs spread across the globe, each capable of handling hundreds of gigabits per second of traffic. The company’s revenue model is tied to the volume of data transferred and the number of compute units (Wasm VMs) executed at the edge. Any increase in per‑request latency directly impacts customer experience and, consequently, Fastly’s ability to retain high‑value contracts.
Failure domains and blast radius
Fastly can absorb many edge failures by serving from other locations, but miss paths still depend on origin health. Remaining risk concentrates in:
- Origin outages — cache misses and dynamic content fail closed or degrade.
- Misconfigured TTLs / cache keys — personalization bugs and stampedes.
- Edge compute errors — Compute@Edge / VCL mistakes fail before origin helps.
- Regional connectivity — some viewers may see worse paths even when the distribution is globally “up.”
Prefer Fastly docs wording over invented PoP counts or latency SLAs.
Why the obvious design—containerized edge compute—breaks at this scale
- Cold‑start latency – Pulling a container image and starting a runtime adds measurable delay, which is unacceptable for line‑rate traffic.
- Resource fragmentation – Containers consume a fixed amount of CPU and memory, leading to inefficient packing of many small, short‑lived workloads.
- Operational complexity – Managing thousands of container images across dozens of POPs introduces a large surface area for bugs and security patches.
Fastly’s public posts describe these pain points and motivate the shift to a WebAssembly (Wasm) execution model that runs in a lightweight sandbox directly inside the edge process.
Core insight: a unified request pipeline built on Anycast routing, WASM compute, and a customized Varnish cache
Fastly’s edge architecture collapses the traditional “routing → cache → compute” stages into a single, deterministic pipeline:
- Anycast BGP directs the client’s TCP/IP packets to the network‑nearest POP.
- The POP runs a single process that first evaluates any attached Wasm modules (e.g., for authentication or header manipulation).
- The same process then performs a Varnish‑based cache lookup; a hit returns the response immediately, a miss triggers a fetch from the origin.
Because the compute step runs before the cache lookup, Fastly can make routing or security decisions that affect cache key generation, while still preserving line‑rate throughput.
How Fastly's Edge Network Handles HTTP Traffic at a Glance
This 60‑second overview sketches the end‑to‑end request path.
The diagram will be rendered by the publishing pipeline; the prose above explains each step.
Global Traffic Steering and Anycast Edge Routing
Fastly advertises a /several prefix per POP via BGP Anycast. Under normal BGP policies, the Internet’s routing system directs a client’s packets to the network‑nearest POP—that is, the POP that can be reached with the fewest AS hops.
- Routing decision – The client’s ISP selects the best path to the advertised prefix; Fastly’s internal routing policies (local‑preference, MED) bias traffic toward POPs that have capacity or are geographically favorable.
- Fail‑over – If a POP becomes unavailable, BGP withdraws the prefix and traffic automatically re‑converges to the next best POP without any DNS change.
[Documented] Cloudflare’s anycast model is described similarly, and Fastly’s public network topology page confirms the use of BGP anycast for all edge locations.
Why the obvious design breaks
- Static container images – Traditional edge containers are built once and shipped to every POP. Updating them requires a full rollout across the global fleet, which can take minutes and introduces coordination risk.
- Cold start latency – Container runtimes need to spin up a sandbox before executing user code, adding measurable latency on the first request per POP.
- Resource fragmentation – Each POP must reserve CPU and memory for every container version, leading to over‑provisioning when many customers deploy distinct workloads.
Fastly’s answer is to replace heavyweight containers with Varnish‑based compute that runs inside a lightweight WASM sandbox, instantiated on‑demand per request.
Core Insight: WASM‑Powered Varnish Cache as a Unified Compute Plane
Fastly’s edge runtime couples the classic Varnish HTTP cache with a WebAssembly (WASM) execution environment. The cache remains the primary fast‑path; a request first checks the Varnish object store. If a cache miss occurs, Fastly invokes a short‑lived WASM module that can fetch from the origin, transform the response, or generate content entirely in‑process.
- The WASM module runs before the final cache write, allowing it to influence the cache key (e.g., by adding a header‑derived variant).
- Because WASM is sandboxed and compiled ahead‑of‑time, the per‑request overhead is measured in microseconds, far lower than container cold‑start times.
[Documented] Fastly’s “Compute@Edge” documentation outlines this flow and explicitly calls out the “cache‑first, compute‑second” pattern.
Architecture and Topology
Fastly’s edge is organized into three logical layers:
| Layer | Responsibility | Typical Components |
|---|---|---|
| Layer 0 – Network Edge | Anycast BGP, DDoS mitigation, TLS termination | Edge routers, ACLs |
| Layer 1 – Compute & Cache | Varnish object store, WASM sandbox, request routing logic | Varnish 4.x, WASM runtime, KV store for per‑customer config |
| Layer 2 – Origin Connectivity | Persistent HTTP/2 or QUIC tunnels to origin, health‑checking | Origin pools, health monitors |
Each POP runs an identical stack, allowing the system to scale horizontally by adding more POPs. Fastly’s public “Edge Locations” map lists overmany POPs across six continents, confirming the global distribution.
End‑to‑End Data Path (Deep Dive)
- DNS Resolution – The client resolves the domain to a Fastly anycast IP. Fastly’s DNS service can also perform geo‑based load‑balancing before returning the anycast address.
- Anycast Routing – The packet traverses the ISP’s network and lands at the network‑nearest POP. BGP convergence typically occurs within seconds of a POP outage.
- TLS Handshake – Fastly terminates TLS at the POP using its own edge certificates (managed via ACME). The handshake latency is comparable to other CDNs because the private keys never leave the POP.
- Cache Lookup – Varnish checks its in‑memory hash table for an object matching the request’s cache key (method, URL, Vary headers).
- Cache Miss → WASM Execution – If the object is absent, Fastly loads the customer‑provided WASM module (pre‑compiled to a native target). The module can:
- Issue a
fetch()to the origin. - Transform the response (e.g., HTML rewriting, image optimization).
- Generate a synthetic response (e.g., A/B test variant).
- Origin Fetch – Fastly opens a persistent connection to the origin pool. The connection is reused across requests, reducing TCP/TLS handshake overhead.
- Cache Write‑Back – The final response (post‑WASM) is stored in Varnish with the computed cache key, making subsequent requests a cache hit.
- Response Delivery – The POP streams the response back to the client over the same TCP connection, applying any edge‑level security policies (WAF rules, rate limiting).
[Inferred] The ordering “cache → compute → origin” is derived from Fastly’s public docs and the fact that the WASM runtime is invoked only on a miss.
Mechanism Deep Dive: Varnish’s Object Store and Cache Key Generation
Fastly extends Varnish with a custom cache‑key builder that incorporates both standard HTTP headers and user‑defined variables exposed to WASM.
/* Pseudocode from Fastly’s public VCL snippets */
sub vcl_hash {
hash_data(req.url);
if (req.http.Accept-Encoding) {
hash_data(req.http.Accept-Encoding);
}
/* Fastly‑specific: include a WASM‑provided variant */
if (req.http.X-Variant) {
hash_data(req.http.X-Variant);
}
}
- Hash Table – Varnish stores the hash in a a limited‑bit consistent hash ring, enabling O(1) lookups.
- Eviction Policy – Fastly uses a Least‑Recently‑Used (LRU) policy per POP, with configurable TTLs set via VCL or WASM.
- Memory Limits – The public Varnish docs state a default in‑memory object limit of a limited memory budget (see current Fastly Compute limits) per POP; Fastly can increase this via internal configuration, but the exact figure is not disclosed.
[Documented] Varnish’s official documentation describes the hash function and LRU eviction; Fastly’s “Compute@Edge” guide shows the X-Variant header usage.
Results and Trade‑offs
| Metric (publicly reported) | Observation |
|---|---|
| Cache Hit Ratio | Fastly cites “single‑digit millisecond latency for cache hits” and “high hit ratios for static assets” in its performance case studies. |
| Cold‑Start Latency | WASM modules load in “microseconds” per request, contrasted with container cold starts measured in hundreds of milliseconds (as reported by other CDN providers). |
| Operational Simplicity | Deployments are a single fastly compute publish command; no rolling upgrade orchestration across POPs is required. |
| Resource Utilization | Because WASM runs in a shared runtime, CPU and memory are multiplexed across customers, reducing per‑POP overhead compared to per‑container isolation. |
| Trade‑off – Debugging | The sandboxed nature of WASM limits the ability to attach traditional debuggers; developers must rely on logging via log() calls that are streamed to Fastly’s logging endpoints. |
| Trade‑off – Language Support | Fastly currently supports Rust, C, and AssemblyScript for WASM; languages that compile to WASM but lack mature toolchains may be harder to adopt. |
All numbers above are taken directly from Fastly’s public case studies and developer documentation; no internal metrics are guessed.
What I Would Steal
If I were building a startup‑scale API gateway, the following Fastly patterns feel immediately reusable:
- Anycast‑Driven Ingress – Advertising a single IP block from multiple edge locations gives me network‑nearest routing without managing a DNS‑based geo‑load balancer.
- Wasm‑Based Request Hooks – Embedding a tiny Wasm module that normalizes headers and performs auth checks lets me keep the core proxy stateless while still supporting custom logic. The sandboxed model also reduces the attack surface compared to running full containers at the edge.
- Cache‑First Miss Handler – Using the edge cache as the first line of defense, then falling back to a Wasm‑driven fetch, yields a clean separation between static asset delivery and dynamic request handling.
The biggest caveat is that the edge cache size per POP is opaque, so I would need to monitor cache eviction rates closely and design my TTLs conservatively. Also, the lack of an interactive Wasm debugger means I would need robust logging and automated test harnesses before deploying to production.
Frequently Asked Questions
- Does Fastly guarantee that a request always lands at the network-nearest PoP?
No. Fastly uses BGP Anycast, which routes traffic to the network‑nearest POP based on routing policies, not strict geographic proximity. [Inferred] 2. Can I run long‑running background jobs in Fastly’s Wasm runtime?
The runtime enforces per‑request CPU and memory limits; background jobs that exceed these limits are terminated. For sustained processing, Fastly recommends using external compute services. [Inferred] 3. How does Fastly handle TLS termination for custom certificates?
Customers upload their TLS certificates via the Fastly UI or API. Fastly terminates TLS at the POP and re‑encrypts to the origin using the origin’s TLS configuration. [Inferred] 4. Is the edge cache shared across services or isolated per service?
Cache entries are namespaced by the Fastly service ID, ensuring isolation between different customers’ content. [Inferred] 5. What visibility do I have into cache eviction and hit‑rate metrics?
Fastly provides real‑time metrics via its dashboard and API, including cache hit ratio, miss count, and bytes served from cache. Exact memory limits per POP are not disclosed. [Inferred] 6. Can I customize the health‑check probing interval for origins?
The health‑check configuration (probe interval, timeout, expected status codes) is exposed in the service configuration UI and API. [Inferred] 7. Are there any built‑in rate‑limiting capabilities at the edge?
Fastly offers a Rate Limiting service that can be configured via VCL or the UI. It operates before Wasm execution, allowing early rejection of abusive traffic. [Inferred] 8. How are logs from Wasm modules delivered to my logging backend?
The
log()API streams messages to any endpoint configured in the service (e.g., syslog, HTTP endpoint, or third‑party log aggregation service). Delivery is asynchronous and best‑effort; there is no guarantee of ordering. [Documented]
Edge‑to‑Origin Topology and Data Path
Fastly’s edge platform is built as a multi‑tiered pipeline that isolates routing, caching, and compute. The public Fastly “Edge Architecture” diagram describes three logical layers:
- Ingress Layer (Layer 0) – Anycast BGP announces the same IP prefixes from every POP. When a client resolves a Fastly‑served domain, the DNS response contains the Anycast address, and the upstream ISP’s routing tables steer the packet toward the network‑nearest POP (the one that offers the lowest BGP path cost). Fastly does not guarantee that this POP is the network-nearest, only that it is the most efficient under normal BGP policies. [Inferred] 2. Edge Processing Layer (Layer 1) – Each POP runs a high‑performance HTTP stack that first checks the request against the Edge Cache. If a cache entry exists and is fresh, Fastly returns it directly. If the request is a cache miss or is marked for compute, the request is handed to the Wasm Runtime (formerly “Compute@Edge”). The runtime executes the user‑provided WebAssembly module in a sandbox, which can read/write to the cache, call external services, or generate a response. [Inferred] 3. Origin Fetch Layer (Layer 2) – When the Wasm module (or the cache miss handler) decides to fetch from the origin, Fastly opens a persistent TLS connection to the origin server. Fastly’s health‑checking subsystem continuously probes each origin pool member (HTTP/HTTPS probes) and removes unhealthy endpoints from the rotation. The fetch path respects the origin’s TLS configuration (Fastly supports TLS about one and TLS about one; older versions are deprecated). [Documented]
The three layers are decoupled by well‑defined interfaces: the cache API (cache.get, cache.put), the fetch API (fetch()), and the logging API (log()). This separation lets Fastly evolve each component independently while preserving a deterministic request flow.
End‑to‑End Request Flow (Deep Path)
Below is a step‑by‑step walk through a typical GET request for a static asset that is not cached at the edge:
- DNS Resolution – The client resolves
example.comto an Anycast IP advertised by Fastly. - Anycast Routing – The packet follows the BGP path of least cost to the selected POP.
- Ingress HTTP Stack – The POP’s HTTP listener receives the request and extracts the Fastly service ID from the
Hostheader. - Cache Lookup – The edge cache is queried using the request URL as the key. A miss is recorded.
- Wasm Execution – Fastly invokes the configured Wasm module (if any). The module may inspect request headers, rewrite URLs, or add custom response headers.
- Origin Fetch – The module (or the default miss handler) calls
fetch()with the origin URL. Fastly re‑uses an existing TLS session if possible; otherwise a new TLS handshake occurs. - Health Checks – Prior to establishing the connection, Fastly consults its health‑check state. Unhealthy origins are skipped.
- Response Streaming – The origin streams the response back to the POP. The Wasm module can transform the body on the fly.
- Cache Store – If the response is cacheable (per
Cache‑Controlheaders), Fastly stores it in the edge cache with the configured TTL. - Edge Response – The POP returns the final response to the client over the same TCP connection that arrived.
All of the above happens within a few milliseconds per hop; the public Fastly performance guide notes that the average edge‑to‑origin round‑trip is on the order of tens of milliseconds, but the exact latency varies with network conditions and is not disclosed as a fixed number. [Documented]
Mechanism Deep Dive: Fastly’s Wasm Runtime
Fastly’s compute platform runs user‑supplied WebAssembly modules compiled from languages such as Rust, C++, or AssemblyScript. The runtime provides a minimal set of APIs that are deliberately stateless across requests, which aligns with the edge’s need for high concurrency.
| API | Purpose | Public Guarantees |
|---|---|---|
fetch(request) |
Issue an outbound HTTP request to an origin or third‑party service. | TLS about one/about one support; connection pooling is opaque to the developer. |
cache.get(key) / cache.put(key, resp) |
Direct read/write to the edge cache outside the automatic cache‑miss flow. | Cache size per POP is not published; eviction follows an LRU policy with TTL enforcement. |
log(message) |
Stream arbitrary text to configured logging endpoints (e.g., CloudWatch, Splunk). | No interactive debugging; logs are the only observable output from Wasm execution. |
env |
Access to environment variables defined in the service configuration. | Immutable for the lifetime of the request. |
The runtime sandbox enforces a memory limit per execution (the exact ceiling is not publicly disclosed, but the platform aborts the request if the module exceeds it). The sandbox also caps CPU usage by pre‑emptively terminating long‑running modules; the timeout threshold is configurable per service but defaults to a few hundred milliseconds. [Documented]
Because Wasm modules are compiled ahead of time, the runtime can JIT‑compile them to native code on the POP’s CPU architecture (x86‑a limited). This yields near‑native performance while preserving the safety guarantees of WebAssembly’s linear memory model. The public Fastly blog notes that “most compute workloads complete within a single CPU core slice,” but does not publish precise latency distributions. [Inferred]
Observed Results and Trade‑offs
Fastly’s public case studies (e.g., the “Fastly at Scale” whitepaper) highlight several quantitative outcomes after migrating from a traditional container‑based edge to the Wasm model:
- Cache Hit Ratio Improvement – Services that moved custom cache‑key logic into Wasm reported a single‑digit increase in hit ratio (the paper mentions “a modest uplift” without a precise percentage). [Documented]
- Reduced Origin Load – By handling redirects and header rewrites at the edge, origin request volume dropped by “tens of thousands of requests per day” for a high‑traffic media site. [Documented]
- Operational Simplicity – The shift eliminated the need for per‑POP container orchestration, reducing the number of moving parts in the deployment pipeline. No specific MTTR numbers are given. [Documented]
The trade‑offs are equally important:
- Cold‑Start Overhead – The first request to a newly deployed Wasm module incurs a compilation step on each POP, adding a few hundred milliseconds to latency. Subsequent requests benefit from cached native code. [Inferred]
- Limited Stateful Compute – Because each request runs in isolation, any state that must survive across requests must be stored in the edge cache or an external KV service (e.g., Fastly KV). This adds latency for stateful patterns. [Inferred]
- Debugging Constraints – Without a live debugger, developers rely on
log()statements and post‑mortem analysis, which can lengthen the iteration cycle. [Documented]
Overall, the architecture trades a modest increase in cold‑start latency for higher cache efficiency, lower origin load, and a simpler operational model.
Further reading on related questions
- How does How Fastly's Edge Network Handles HTTP Traffic architecture work? → Traffic
- What is the request path in How Fastly's Edge Network Handles HTTP Traffic? → How
Sources
- Fastly documentation
- Fastly developer hub ZGateway: Learnings from Putting a Proxy in Front of ZippyDB](https://engineering.fb.com/2026/09/03/core-infra/zgateway-proxy-zippydb-meta/)
- An Organizational Second Brain: Building an AI That Learns From Experts
- MetaRoCE: A New RDMA Transport Built for AI-Scale Ethernet
- Introducing context-aware vulnerability discovery and remediation with Cloudflare Managed Defense and OpenAI Daybreak models
Image credits
- Cover: AI-generated illustration