HTTP/2 Server Push: How It Works and Why It Failed

Learn about HTTP/2 Server Push, why it was introduced, how it works, and why it was largely abandoned in favor of Early Hints (103) in HTTP/3.

Security

Detailed Explanation

HTTP/2 Server Push: A Good Idea That Did Not Work

Server Push was one of HTTP/2's headline features. It allowed the server to proactively send resources to the client before they were requested. In practice, it proved problematic.

How Server Push Works

When a client requests an HTML page, the server can anticipate that CSS, JS, and images will be needed. Using PUSH_PROMISE frames, the server sends these resources without waiting for the client to request them.

Without push:                 With push:
Client      Server            Client      Server
  |--GET /-->|                  |--GET /-->|
  |<--HTML---|                  |<--HTML---|
  |          |                  |<--CSS----|  (pushed)
  |--GET css->|                 |<--JS-----|  (pushed)
  |<--CSS----|
  |--GET js-->|
  |<--JS-----|

Why It Failed

  1. Cache duplication: If the client already has the CSS cached, the pushed data wastes bandwidth. The client can send RST_STREAM to cancel, but data may already be in-flight.

  2. Complexity: Deciding what to push requires the server to know what the client already has cached. HTTP/2 proposed Cache Digests to solve this, but the specification was never finalized.

  3. Priority inversion: Pushed resources compete with the HTML response for bandwidth, potentially delaying the very page that needs them.

  4. Implementation difficulty: Many servers and CDNs implemented push incorrectly or not at all.

  5. Negligible benefit: Measured improvements were typically < 2%, and sometimes push made things worse.

The Alternative: Early Hints (103)

The 103 Early Hints status code (RFC 8297) provides a lighter approach. The server sends a preliminary response with Link headers that hint which resources to preload:

HTTP/1.1 103 Early Hints
Link: </style.css>; rel=preload; as=style
Link: </app.js>; rel=preload; as=script

HTTP/1.1 200 OK
Content-Type: text/html

The browser sees these hints and starts fetching resources immediately, while the server finishes generating the full response. This avoids the cache duplication and priority problems of push.

Status in HTTP/3

HTTP/3 technically supports server push, but it is rarely implemented and Chrome has removed push support entirely. Early Hints is the recommended approach.

Use Case

Web developers who have been considering HTTP/2 Server Push should understand why the industry moved away from it. If you need to speed up resource loading, use Early Hints (103), preload resource hints, or preconnect hints instead. This knowledge prevents investing time in a deprecated feature.

Try It — HTTP/2 vs HTTP/3 Comparison

Open full tool