Shopify serves cacheable pages from its Full Page Cache (FPC) at the edge. When the same URL returns a different ETag on every request, the page is being re-rendered per visitor and never benefits from the cache — the single biggest lever on storefront speed.
Why it happens
- Session-dependent Liquid in global templates. Referencing
cart,customer, orlocalizationobjects intheme.liquid, the header, or other sitewide sections forces a personalised render of every page. - Per-request randomness.
{{ 'now' | date }}, random product shuffles, or A/B snippets injected server-side change the HTML each time. - App-injected blocks that write request-specific markup into shared sections.
How to fix it
- Move cart/customer logic to the client. Render an empty cart shell server-side and hydrate it with the Cart AJAX API (
/cart.js) after load. - Keep
theme.liquidand the header/footer free ofcustomerandcartobject reads. - Audit apps one at a time — disable, re-test the ETag across three requests, re-enable — to find the one breaking cache.
How to verify
Request the page three times and compare headers. A warm cache shows a stable ETag and server processing under ~100ms on the 2nd/3rd request:
curl -sI https://yourstore.com | grep -i 'etag\|server-timing'