← Back to blog
Performance· October 1, 2026 ·6 min read

ESI explained: cache the page, personalize the bits

The classic caching dilemma: the page is 99% identical for everyone, but that 1% — the username, the cart count — makes the whole thing uncacheable. ESI is one of two ways out, and it is not always the right one.

Mads Edelskjold
Mads Edelskjold
Founder, NordicCDN · ex-datacenter CTO
ESI explained: cache the page, personalize the bits
The short version

Edge Side Includes let you cache a page in full while marking small regions as separate fragments the edge fills in per visitor — a cart count, a greeting, a personalised banner. Each fragment gets its own cache rules, so one page can combine content cached for a day, content cached for a minute, and content never cached at all. The main alternative is fetching those fragments client-side, and which one wins depends on whether the fragment affects layout.

Here is a frustration anyone who caches dynamic sites knows well. A page is essentially identical for every visitor — same layout, same products, same copy — except for one small personal corner. The cart count in the header. The "Hi, Sara". And because of that one corner, the entire page gets marked uncacheable and rebuilt from scratch for every request.

It is a bad trade, and there are two established ways out of it. ESI is the older one and it is still the better one in specific circumstances, which are worth knowing precisely.

How ESI works

Your origin returns a page containing placeholder tags instead of the dynamic parts:

<header>
  <esi:include src="/fragments/cart-summary" />
</header>

That page — placeholder and all — is cached at the edge as a normal cacheable response. When a visitor requests it, the edge serves the cached shell and, before sending, fetches each fragment and substitutes it in. The fragment request carries the visitor's cookies, so it can be personalised, and it has its own cache rules independent of the page.

Cached page shell (fast) dynamic fragmentcart: 3 items · Hi, Sara
Cache the whole shell; only the small highlighted fragment is personal.

The important consequence is that one page can now carry several different caching strategies simultaneously. The shell caches for a day. A "trending right now" block caches for sixty seconds and is shared by everyone. The cart fragment is personal and never cached. All assembled at the edge, all delivered as one HTML document.

ESI versus fetching it in the browser

The obvious alternative is to leave a gap in the HTML and fill it with JavaScript after the page loads. That works, it is simpler to build, and for a great many cases it is the right answer.

The distinction that decides it is whether the fragment is in the HTML when it reaches the browser.

ESIClient-side fetch
Present in initial HTMLYesNo
Causes layout shiftNoYes, unless space is reserved
Extra browser round tripNoneOne per fragment
Works without JavaScriptYesNo
Visible to crawlersYesSometimes, unreliably
Implementation complexityEdge configuration requiredOrdinary front-end work
Slow fragment delays the pageYes — it blocks the responseNo — page renders first

Read the last two rows together, because they are the trade. ESI gives you a complete document with no layout shift and no extra round trip, at the cost of the page being only as fast as its slowest fragment. Client-side fetching gives you a page that renders immediately regardless, at the cost of content arriving late and moving things.

So: if the fragment affects layout or matters to a crawler, use ESI. A personalised hero banner that changes the page's height should not arrive 400 milliseconds late — that is a Cumulative Layout Shift problem you have created deliberately. If it is a small detail in a corner, fetch it client-side. A cart count badge in the header does not justify edge configuration.

The failure mode to design against is a fragment that hangs. Because ESI assembles before responding, a fragment endpoint that takes three seconds makes the whole page take three seconds — even though the shell was a cache hit. Set an aggressive timeout on every fragment and define what renders if it is not met, so a struggling fragment service degrades to a missing cart count rather than an unusable site.

Where it earns its place

Good fit

  • High-traffic pages with one or two personal elements
  • Fragments that affect layout above the fold
  • Sections with genuinely different freshness needs on one page
  • Sites that must work without JavaScript

Not worth it

  • Pages that are personal throughout
  • Small badges and counters in corners
  • Low-traffic pages where caching saves little
  • Anything a simple fetch handles adequately

ESI is a specialised tool and it should feel like one. If you are reaching for it on a page where three quarters of the content is per-visitor, you are fighting the mechanism — that page is genuinely dynamic and should be treated as such.

Common questions

What is ESI (Edge Side Includes)?

ESI is a markup language that lets a cached page contain placeholder tags for dynamic fragments, which the CDN edge fetches and substitutes before returning the response. This allows a page to be cached in full while small personalised regions — a cart count, a user greeting — are assembled per visitor, each with its own independent cache rules.

When should I use ESI instead of a client-side fetch?

Use ESI when the fragment affects layout or needs to be visible to crawlers, since ESI content is present in the HTML that reaches the browser and causes no layout shift or additional round trip. Use a client-side fetch for small details that do not affect layout, where the simplicity of ordinary front-end code outweighs the benefit and a late arrival is harmless.

Does ESI slow down page delivery?

It can, because fragments are assembled before the response is sent, so the page is only as fast as its slowest fragment. A fragment endpoint that hangs will delay a page that was otherwise a cache hit. Always configure a short timeout per fragment along with fallback content, so a failing fragment degrades gracefully instead of blocking the whole response.

Can different parts of one page have different cache times with ESI?

Yes, and that is its main advantage. The page shell might be cached for a day, a trending-products fragment for sixty seconds and shared between all visitors, and a cart fragment not cached at all. The edge assembles them into a single HTML response, so one document combines several caching strategies.

The framing worth keeping: ESI is not a caching technology so much as an assembly one. It lets you stop treating a page as a single cacheable unit and start treating it as several — which is usually a much more accurate description of what the page actually is.

#esi #caching #performance #personalization
Put it into practice

See how NordicCDN does this for your site:

Mads Edelskjold
Written by
Mads Edelskjold — Founder, NordicCDN · ex-datacenter CTO

Mads has worked in IT — mostly hosting — since he was 16. He took an early stake in a SaaS company and helped grow it through to its acquisition by Visma, has built and run data-center networks, and served as CTO of a Danish data center. He started NordicCDN to make fast, secure infrastructure simple to use.

Make your site load instantly

Start free in two minutes — no card required.

Start free