The most surprising thing about Alt-Svc headers is that they allow a server to advertise other ways to connect, potentially bypassing the very connection the header is being sent over.

Let’s see it in action. Imagine a client connecting to example.com on port 443.

GET / HTTP/1.1
Host: example.com
User-Agent: curl/7.81.0
Accept: */*

HTTP/1.1 200 OK
Content-Length: 1234
Content-Type: text/html
Server: Apache/2.4.54
Alt-Svc: h3=":443"; ma=2592000, h3-29=":443"; ma=2592000

See that Alt-Svc line? It’s telling the client, "Hey, you connected to me via HTTP/1.1 on port 443, but you could also reach me using HTTP/3 (protocol h3) on the same port 443. This option is valid for 2592000 seconds (30 days)."

This is crucial for rolling out new protocols like HTTP/3. You can’t just flip a switch and force everyone to use it. Clients might not support it, or network intermediaries could block it. Alt-Svc provides a graceful fallback and discovery mechanism.

Here’s how it builds the mental model:

  1. The Problem: Efficiently migrating to new, faster, or more secure protocols (like HTTP/3) without breaking existing clients or requiring massive infrastructure changes upfront. Clients need to discover that a new protocol is available and how to use it.
  2. The Solution: Alt-Svc Header: When a client makes a successful HTTP/1.1 or HTTP/2 connection to a server, the server can include an Alt-Svc header in its response. This header lists alternative services the server can be reached at.
    • h3: This is the identifier for HTTP/3.
    • h3-29: This is an older, draft version of HTTP/3, still sometimes advertised for backward compatibility.
    • =":443": Specifies the port number for the alternative service. In this case, it’s the same port as the original connection.
    • ma=2592000: max-age in seconds. This tells the client how long it should remember this alternative service information.
  3. The Client’s Role: A compliant client, upon receiving this header, will:
    • Parse the Alt-Svc header.
    • Cache the advertised alternative services and their max-age.
    • For future connections to example.com, it will first attempt to use one of the advertised alternative services if it supports them. If HTTP/3 is advertised and the client supports it, it will try to establish an HTTP/3 connection directly to example.com:443 without going through the initial HTTP/1.1 handshake.
    • If the HTTP/3 connection succeeds, great! The client then uses HTTP/3 for subsequent requests.
    • If the HTTP/3 connection fails (e.g., port blocked, server not actually ready), the client falls back to the original protocol (HTTP/1.1 or HTTP/2) and continues as if the Alt-Svc header wasn’t there. It might even mark that specific Alt-Svc entry as non-functional for a while.

This allows for a seamless "opt-in" experience. The server advertises, and the client decides whether to try the new path. If it works, great. If not, the user is unaffected. This is how major browsers and CDNs have gradually adopted HTTP/3.

The Alt-Svc mechanism is not just for HTTP/3. It can be used to advertise other protocols or even different network endpoints. For instance, a server might advertise a UDP-based QUIC endpoint even if the current connection is TCP-based. The protocol-id part of the Alt-Svc header is extensible.

When configuring your web server (like Nginx or Apache) to advertise HTTP/3 support, you’re essentially telling it to include this Alt-Svc header in its responses once it’s capable of serving HTTP/3. For Nginx, this typically involves enabling the http3 module and setting the alt-svc directive in your listen configuration. For example:

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name example.com;

    # ... other SSL and server config ...

    # Advertise HTTP/3 support
    add_header Alt-Svc 'h3=":443"; ma=2592000, h3-29=":443"; ma=2592000';

    # ... rest of your server config ...
}

# If you have a separate listener for HTTP/3 (e.g., UDP)
server {
    listen 443 quic reuseport; # Example for QUIC/HTTP/3
    server_name example.com;

    # ... other QUIC/HTTP/3 config ...
}

The add_header directive is what injects the Alt-Svc line into the HTTP response. The ma value is critical; too short and clients won’t cache it effectively, too long and clients might keep trying a service that’s no longer available. 30 days (2592000 seconds) is a common and reasonable default.

The trickiest part of implementing Alt-Svc is ensuring your server actually supports the advertised alternative. If you advertise h3=":443" but your server isn’t configured to listen for and handle HTTP/3 connections on port 443, clients will attempt to connect via HTTP/3, fail, and then fall back. While this doesn’t break functionality, it adds latency and can lead to a degraded user experience. Therefore, the Alt-Svc header should only be added to responses from servers that are fully ready to serve traffic over the advertised protocols.

The next step after successfully advertising HTTP/3 is understanding how clients prioritize and probe these alternative services.

Want structured learning?

Take the full Http3 course →