Skip to main content

HTTP/2 and HTTP/3 (QUIC) in Nginx: Enabling and Testing

Nginx · 29.09.2026

How HTTP/2 and HTTP/3 differ from HTTP/1.1

HTTP/1.1 opens a separate TCP connection for several parallel requests and sends headers as plain text with every request. HTTP/2 multiplexes requests over a single connection and compresses headers, so a page with dozens of small files loads faster. HTTP/3 goes further — it moves the transport from TCP to QUIC over UDP, so one lost packet no longer stalls every other stream at once, which can happen with HTTP/2.

For a site on a ZevsHost.net VDS with visitors on mobile networks with packet loss, switching to HTTP/3 gives a noticeable responsiveness boost. For an ordinary corporate site on a stable link, the difference between HTTP/2 and HTTP/3 is barely noticeable — there, properly configured SSL/TLS matters more, since without it neither HTTP/2 nor HTTP/3 will work at all.

Enabling HTTP/2 in Nginx

Since version 1.25.1 the listen ... http2 directive is deprecated, replaced by a separate http2 on; directive inside the server block.

server {
    listen 443 ssl;
    http2 on;
    server_name example.com;

    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
}

HTTP/2 only works over TLS in the vast majority of browsers, so without a valid certificate the directive is effectively useless. You can check the Nginx version with nginx -v, and the current way to install a recent version on Ubuntu and Debian is described in the article on installing Nginx.

Enabling HTTP/3 and QUIC

HTTP/3 requires an Nginx build with QUIC support (available starting with version 1.25.0 in the mainline branch) and an open UDP port in addition to TCP.

server {
    listen 443 ssl;
    listen 443 quic reuseport;
    http2 on;
    http3 on;
    server_name example.com;

    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

    add_header Alt-Svc 'h3=":443"; ma=86400';
}

The Alt-Svc header tells the browser that the server supports HTTP/3 on the same port — without it the browser keeps connecting over HTTP/2 even if QUIC is already configured. Port 443/udp must be opened in the firewall separately from 443/tcp, otherwise the connection simply will not be established.

Protocol versions and requirements

ProtocolTransportMinimum for Nginx
HTTP/1.1TCPany version
HTTP/2TCP + TLS1.9.5, http2 on directive since 1.25.1
HTTP/3QUIC + UDP1.25.0 with a QUIC-enabled build

A build from the distribution's default repository does not always include QUIC — you often need the official nginx.org repository with a package built with the --with-http_v3_module flag. You can check whether the module is present with nginx -V 2>&1 | grep http_v3.

Checking that the protocol is really being used

  • curl -I --http2 https://example.com/ — the response should contain the line HTTP/2 200.
  • curl -I --http3 https://example.com/ — available if your local curl is built with HTTP/3 support.
  • The Network tab in browser developer tools — the Protocol column shows h2 or h3.
  • The Alt-Svc response header is present and points to the correct port.

If the browser keeps using HTTP/2 after HTTP/3 is enabled, the problem is most often a closed UDP port in the firewall or a missing Alt-Svc header — the TCP connection still works fine, so the site opens, just without the speedup from QUIC.

Summary: HTTP/2 and HTTP/3 checklist for Nginx

  • The server block has http2 on; and, if needed, http3 on;.
  • Nginx is built with the http_v3 module if HTTP/3 is planned.
  • Port 443/udp is open in the firewall separately from 443/tcp.
  • The Alt-Svc header is added and points to the correct port.
  • The protocol has been checked with curl -I and the browser Network tab, not just assumed.
← Back to Knowledge Base Ask Support