Early Hints

The content on this page uses the following versions of Compute SDKs: JavaScript SDK: 3.42.1 (current), Rust SDK: 0.12.1 (current), Go SDK: 1.7.0 (current), C++ SDK: 0.6.0 (current)

103 Early Hints is an informational response code that allows the server to send a "pre-response" to the browser while it is still generating the main HTML.

Traditionally, when a user visits a website, a frustrating game of back-and-forth happens behind the scenes:

  1. The Request: The browser asks the server for index.html.

  2. The Server "Think" Time: The server receives the request, but it can't send the HTML immediately. It has to talk to databases, call APIs, and assemble the page. This often takes anywhere from 100ms to over a second.

  3. The Idle Browser: During this time that the server is "thinking", the browser's network connection sits completely idle.

  4. The Discovery Delay: Only after the server finishes and sends the HTML can the browser look inside it, discover the critical CSS and JavaScript files, and then start downloading them.

This creates a massive bottleneck where the user is staring at a blank screen while assets wait in a queue.

Your edge code can make use of 103 Early Hints to send instructions to the browser during this "idle browser" period. In effect, your code tells the browser that, while the server is still working on the HTML, the browser is going to need certain resources such as CSS, JS, and other files. The browser can then go ahead and start downloading them in the meantime.

How it works

In a standard HTTP setup, a server can only send one response header per request. However, the HTTP specification allows servers to send interim (temporary) responses before the final one, as long as they use a 1xx status code. Early Hints leverages this capability to send two sets of headers: an interim 103 response, followed by the final 200 response.

If you were to look at the literal bytes traveling over the network cable during that single request, it looks like this:

IMPORTANT: Fastly only supports 103 Early Hints over HTTP/2 or HTTP/3. While the examples below are shown in a text-based format for readability, HTTP/2 and HTTP/3 are binary protocols that transmit these messages as separate binary HEADERS frames.

  1. The Client Request

    The browser opens a connection and asks for the page.

    GET /homepage HTTP/2
    Host: example.com
  2. The Interim Response (The "Early Hint")

    The server immediately sends back the 103 headers. Crucially, the server does not close the connection and does not send a body yet.

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

    Note the blank line at the end of the response here. Normally, this means "end of headers," and because it's a 1xx code, the browser knows to keep listening for the next status code.

  3. The Final Response

    While the browser is off downloading main.css and app.js, the server finishes thinking and sends the final, official response down the exact same pipe:

    HTTP/2 200 OK
    Content-Type: text/html
    Content-Length: 4096
    <!DOCTYPE html>
    <html>
    <head>...</head>
    <body>...</body>
    </html>

    Only now, after the 200 OK header and body are fully delivered, is the specific request-response transaction considered finished.

Implementing Early Hints in edge code

Fastly's platform has support for sending Early Hints in edge code. It is only effective for clients connecting using HTTP/2 or later.

  1. Fastly VCL
  2. Rust
  3. JavaScript
  4. Go
  5. C++

In a VCL service, call the early_hints function.

sub vcl_recv {
if (fastly_info.is_h2 || fastly_info.is_h3) {
early_hints("Link: </css/style.css>; rel=preload; as=style", "Link: </main/app.js>; rel=preload; as=script");
}
}