Networking & ProtocolsHTTP/HTTPS & Protocol EvolutionMedium⏱️ ~3 min

HTTP/2 Server Push vs Preload: Why Push Failed at Scale

The Promise of Server Push

HTTP/2 introduced Server Push to allow servers to proactively send resources before the client requests them. The concept was compelling: after the server sends the HTML document, it could immediately push the referenced CSS and JavaScript files, saving one RTT (round-trip time) per resource on a cold cache (when the browser has no cached copy). Instead of the browser parsing HTML, discovering it needs style.css, and then requesting it, the server would push style.css alongside the HTML. For a page referencing 5 critical resources, this could theoretically save 400ms on an 80ms RTT connection.

The Cache Coordination Problem

Production deployments revealed a fundamental problem: the server cannot reliably know what the client has cached. If the server pushes a 200KB JavaScript bundle that the browser already has cached, it wastes bandwidth and potentially evicts other cached resources. This cache coordination problem proved intractable at scale. Without complex state synchronization between client and server (which would add latency and complexity defeating the purpose), the server must guess. Guessing wrong wastes bandwidth, and on mobile connections with metered data or slow speeds, this waste directly harms user experience. Empirical measurements found that naive push strategies often pushed assets already cached 60-80% of the time on returning visitors.

Prioritization Conflicts

Server Push also complicates resource prioritization. Pushed resources compete for bandwidth with the HTML document itself. If the server pushes large JavaScript bundles while still sending HTML, it can delay first byte of critical inline content, degrading FCP (First Contentful Paint, when the browser first renders something visible). The browser's resource scheduler is carefully tuned to prioritize critical rendering path resources; push bypasses this intelligence. Measurements found push strategies frequently degraded page load time by 5-10% in the median case and up to 20% in worst cases when pushing large bundles already cached.

Modern Alternatives

Modern best practice has converged on client-driven alternatives that preserve cache awareness. HTTP 103 Early Hints allows servers to send Link preload headers before the full HTML response is ready. The server sends a 103 response with hints like Link: </style.css>; rel=preload, and the browser initiates fetches while waiting for the 200 response. The browser retains full cache awareness: if style.css is cached, it simply skips the fetch. This achieves equivalent RTT savings without push's downsides. Resource preload directives in HTML (<link rel=preload>) serve similar purposes for resources discovered during HTML parsing.

Industry Outcome

Major platforms have largely disabled or severely limited Server Push in favor of client-driven alternatives. The HTTP/3 specification deprioritized push semantics accordingly, effectively acknowledging the feature's failure in practice. At scale, the bandwidth waste is substantial: at 10 million requests per hour, pushing 100KB assets already cached 70% of the time wastes approximately 700GB of egress bandwidth, translating to significant infrastructure costs. The lesson: features that seem theoretically beneficial can fail when real-world complexity (caching, prioritization, network variability) is considered.

Key Insight: Server Push failed because the server cannot know client cache state. HTTP 103 Early Hints and preload directives achieve similar RTT savings while preserving browser cache awareness. Let the client decide what to fetch.
💡 Key Takeaways
Server Push requires predicting client cache state, which is impossible without complex synchronization; pushing cached assets wastes significant bandwidth
Pushed resources compete for bandwidth with HTML, potentially delaying First Contentful Paint by 50-200ms when pushing large already-cached bundles
Naive push strategies degraded page load by 5-10% median, up to 20% worst case; pushed assets were already cached 60-80% of time for returning visitors
HTTP 103 Early Hints and rel=preload achieve equivalent RTT savings while preserving client-side cache awareness; now the preferred approach
📌 Interview Tips
1Explain the cache problem: server pushes 200KB bundle; browser already has it cached; now you wasted 200KB of bandwidth and potentially evicted other cache entries
2Describe the alternative: 103 Early Hints tells browser "you'll need style.css"; browser checks cache, only fetches if missing; same RTT savings, no waste
3Common follow-up: when might push still work? Answer: first-time visitors with known asset sets, but even then 103 Early Hints is simpler and safer
← Back to HTTP/HTTPS & Protocol Evolution Overview