Edge Side Includes (ESI): Dynamic Assembly at the CDN Edge

· Alex Petrov · 7 min read

Edge Side Includes (ESI) is a markup language that instructs CDN edge servers to assemble web pages from independently cached fragments. Originally submitted to the W3C in 2001 by Akamai and Oracle, ESI solves a fundamental CDN challenge: how to cache pages that contain a mix of static and dynamic components. Rather than treating the entire page as uncacheable because one element — a shopping cart count, a personalized greeting, or a live stock ticker — changes per user, ESI lets each fragment carry its own cache policy while the edge node stitches them together on every request.

How Does ESI Work at the CDN Edge?

ESI operates on a template-and-fragment model. The origin server returns an HTML document containing ESI markup tags instead of final content for dynamic sections. When the CDN edge node processes this template, it recognizes the ESI tags, fetches each referenced fragment (from cache or origin), and assembles the complete page before delivering it to the client. The browser never sees ESI markup — it receives a fully assembled HTML document.

CDN Cache Hierarchy — Multi-tier caching architecture from edge to originCDN Cache Hierarchy — Multi-tier caching architecture from edge to origin CDN Cache Hierarchy — Multi-Tier Architecture L1 Edge Cache Hit Rate: 95% Latency: < 5ms miss L2 Regional Cache Hit Rate: 85% Latency: 10–30ms miss Origin Shield Hit Rate: 70% Latency: 50–80ms miss Origin Server Hit Rate: — Latency: 100–300ms
Figure 1: CDN Cache Hierarchy — Multi-tier caching architecture from edge to origin

The core tag is <esi:include>, which specifies a URL for a fragment to be fetched and inserted inline. A product page template might contain a cached product description, a cached navigation bar, and an <esi:include> pointing to a per-user cart summary endpoint. The product description caches for hours, the navigation for minutes, and the cart fragment is fetched fresh or cached briefly per session cookie. This granular control is impossible with whole-page caching strategies alone.

What ESI Tags Are Available in the Specification?

The ESI specification defines several tags beyond the basic include directive. Understanding each tag's role is essential for designing effective fragment architectures.

Performance Comparison: Edge vs Origin Processing
Metric Edge Processing Origin Processing Improvement
Latency (p50)8–15 ms120–300 ms15–20x faster
Cache Hit Ratio85–95%N/AReduces origin load
TLS Handshake1–5 ms (nearby PoP)50–150 ms10–30x faster
Bandwidth Cost$0.01–0.04/GB$0.05–0.12/GB3–5x cheaper
Availability99.99% (multi-PoP)99.9% (single DC)10x fewer outages

Include and Alternative Sources

The <esi:include> tag accepts a src attribute pointing to the fragment URL and an optional alt attribute specifying a fallback URL if the primary source fails. The <esi:try>, <esi:attempt>, and <esi:except> tags provide more sophisticated error handling, allowing inline fallback content when a fragment fetch fails entirely. This resilience is critical because a single failing fragment should not break the entire page.

Conditional Logic

The <esi:choose>, <esi:when>, and <esi:otherwise> tags enable conditional content selection at the edge. Combined with <esi:vars> — which exposes request variables like cookies, HTTP headers, query strings, and geolocation data — these constructs allow the edge to select different fragments based on user context without origin involvement. For example, a geo-targeted promotion can display different offers to users in different countries, with each variant cached independently at the appropriate regional PoPs.

Content Removal

The <esi:remove> tag marks content that should be stripped when ESI processing is active. This serves as a graceful degradation mechanism: the content inside <esi:remove> renders in browsers or servers that do not process ESI, but disappears when the edge node assembles the page. Paired with <esi:include>, this creates a fallback experience for development environments where ESI is not available.

Which CDN Providers Support ESI and How Do They Differ?

ESI support varies significantly across CDN platforms in both completeness and configuration approach.

ProviderESI Tags SupportedConfiguration MethodMax FragmentsNested Includes
AkamaiFull specificationProperty Manager rulesUnlimited (practical)Up to 3 levels
Varnish Cacheinclude, remove, vars (partial)VCL directivesConfigurableUp to 5 levels
Fastlyinclude, removeVCL + edge dictionaryConfigurableLimited
Oracle Cloud CDNinclude, try/exceptPolicy configurationPer policy limits1 level
Squid Proxyinclude (basic)squid.conf directivesConfigurableNot supported

Akamai provides the most complete ESI implementation, which is expected given that Akamai co-authored the specification. Their Property Manager allows fine-grained control over ESI processing, including fragment timeout settings, error handling behavior, and cache key configuration per fragment. Varnish Cache, the popular open-source reverse proxy, supports a practical subset of ESI that covers the majority of real-world use cases. Fastly, built on Varnish, inherits this support and extends it through custom VCL logic.

How Does Fragment Caching Improve Performance Over Whole-Page Caching?

Fragment caching transforms cache hit ratios for pages that were previously uncacheable. Consider an e-commerce product page with five components: header navigation, product details, pricing, related products, and a user-specific recommendations panel. Without ESI, the entire page is either cached (serving stale recommendations) or uncached (every request hits the origin). With ESI, four of five fragments cache with high TTLs, and only the recommendations fragment requires a per-request origin fetch.

Cache Decision Flow — How the CDN determines cache hit vs missCache Decision Flow — How the CDN determines cache hit vs miss CDN Request Flow — From Browser to Edge CDN Request Lifecycle Step 1 DNS Lookup Step 2 TCP Connect Step 3 TLS Handshake Step 4 Edge Server Step 5 Cache Check Step 6 Response Cache HIT → 5ms response Cache MISS → Fetch origin 0ms ~50ms (cache hit) ~200ms (cache miss)
Figure 2: Cache Decision Flow — How the CDN determines cache hit vs miss

The mathematical impact is significant. If the four cacheable fragments represent 90% of the page's data volume, overall origin bandwidth drops by roughly 90% even though one fragment remains dynamic. Edge assembly typically adds 1 to 5 milliseconds of processing time — far less than the 50 to 200 milliseconds an origin round-trip would cost. The net result is both faster page loads and dramatically lower origin infrastructure costs.

TTL Strategies per Fragment

Each fragment should carry a TTL aligned to its volatility. Navigation elements that change during deployments can cache for 5 to 15 minutes. Product descriptions that update daily can cache for 1 hour. Static footer content can cache for 24 hours. User-specific fragments can use no-cache or very short TTLs (10 to 30 seconds) combined with stale-while-revalidate to balance freshness and performance. This per-fragment TTL granularity is ESI's core advantage over binary whole-page caching decisions.

How Can ESI Enable Personalization Without Sacrificing Cache Performance?

Personalization at the edge through ESI follows a segmented approach. Rather than creating a unique page variant for every user, ESI templates select from a finite set of pre-cached fragment variants based on user attributes. Geographic segments (country, region, language), device segments (mobile, desktop, tablet), and user-type segments (anonymous, logged-in, premium) each map to a cached fragment variant.

The <esi:vars> tag enables this by making request-level variables available in the template. A cookie value indicating the user's preferred language can select between cached fragment variants for English, Spanish, and French content. Geolocation headers can select regional pricing fragments. The edge node resolves these variables, constructs the appropriate fragment URLs, and assembles the page — all without custom edge function code.

This approach works well for coarse-grained personalization with a manageable number of segments. When personalization requires truly individual content (a user's name, specific order history, or ML-generated recommendations), those fragments must either be fetched from the origin on each request or served through more flexible edge personalization techniques built on edge functions.

What Are the Performance and Complexity Trade-offs of ESI?

ESI introduces a processing layer at the edge that carries both benefits and costs. On the benefit side, ESI reduces origin load, improves cache efficiency, and enables personalization without full-page cache busting. On the cost side, it adds architectural complexity, debugging difficulty, and potential latency from sequential fragment fetches.

Fragment fetch waterfall is the primary performance risk. If the template references eight fragments and the edge node fetches them sequentially, each origin-bound fetch adds its full round-trip latency. Most ESI implementations mitigate this by fetching fragments in parallel, but nested includes (a fragment containing its own ESI tags) create unavoidable sequential dependencies. Best practice limits nesting to two levels and keeps the total fragment count under ten per page.

Debugging ESI pages requires visibility into the edge assembly process. Without proper tooling, developers face a page that works in the development environment (where ESI is not processed) but fails in production (where fragment fetches, timeouts, and error handling introduce new failure modes). Akamai's Pragma debug headers and Varnish's varnishlog output provide fragment-level visibility, but this observability layer must be deliberately configured.

Should You Use ESI or Modern Edge Functions?

For new implementations, edge functions generally offer a better developer experience than ESI. Cloudflare Workers, Lambda@Edge, and Deno Deploy provide full programming language support, integrated debugging, version control, and testing workflows that ESI's declarative markup cannot match. Edge functions can also perform logic that ESI cannot express, such as cryptographic operations, complex routing decisions, and real-time data transformations.

ESI remains the right choice when your organization is already invested in Akamai or Varnish infrastructure, when the page composition logic is purely declarative (include fragment A, conditionally include fragment B based on geography), or when you need to avoid the operational overhead of deploying and maintaining edge function code. ESI's declarative model is also inherently safer — there is no risk of infinite loops, memory leaks, or CPU exhaustion that edge function bugs can introduce.

A hybrid approach is increasingly common: use ESI for straightforward template composition and fragment caching, and use edge functions for complex logic like A/B test assignment, authentication validation, and dynamic content transformation. This lets each technology handle what it does best while avoiding overengineering either layer.

External References

References & Standards: OWASP CDN Security · W3C Web Performance