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

> How to enable HTTP/2 and HTTP/3 over QUIC in Nginx, which version you need, and how to check the browser is really using the new protocol.

## 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](https://www.zevshost.net/en/kb/nginx-ssl-tls-nastroika/) 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](https://www.zevshost.net/en/kb/nginx-ustanovka-ubuntu-debian/).

## 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

| Protocol | Transport | Minimum for Nginx |
| --- | --- | --- |
| HTTP/1.1 | TCP | any version |
| HTTP/2 | TCP + TLS | 1.9.5, http2 on directive since 1.25.1 |
| HTTP/3 | QUIC + UDP | 1.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.

---

Source: https://www.zevshost.net/en/kb/nginx-http2-http3-quic/
