Enabling HTTP/3 on a Nginx site can improve real-world performance on mobile, Wi-Fi, and other unreliable networks by running requests over QUIC and reducing transport-level head-of-line blocking.

HTTP/3 carries HTTP semantics over QUIC on UDP, and Nginx exposes it through a QUIC-capable build, a UDP 443 listener, and the Alt-Svc response header that advertises an h3 alternative for the same origin.

Deployment depends on end-to-end UDP reachability (host firewall, cloud security groups, load balancers), a healthy HTTPS listener on TCP 443 for discovery and fallback, and a cautious rollout because Alt-Svc is cached by clients (start with a small ma, and clear cached advertisements during rollback using Alt-Svc: clear or ma=0).

Steps to enable HTTP/3 in Nginx:

  1. Confirm the site serves HTTPS over TCP 443 before enabling HTTP/3.
    $ curl --head https://example.com
    HTTP/2 200
    server: nginx
    content-type: text/html; charset=utf-8
    ##### snipped #####

    HTTP/3 is commonly discovered via Alt-Svc on an initial TCP connection.

  2. Locate the TLS-enabled server block that terminates HTTPS for the domain.
    $ sudo grep --recursive --line-number --extended-regexp 'listen\s+($begin:math:display$\:\:$end:math:display$:)?443\s+ssl' /etc/nginx 2>/dev/null | head --lines=5
    /etc/nginx/conf.d/example.com.conf:12:    listen 443 ssl http2;
    ##### snipped #####

    Common layouts include /etc/nginx/nginx.conf, /etc/nginx/conf.d/*.conf, and /etc/nginx/sites-enabled/.

  3. Confirm the running Nginx build supports the http3 directives.
    $ nginx -V 2>&1 | grep --extended-regexp -- '--with-http_v3_module|--with-http_quic_module'
    --with-http_v3_module

    No match typically indicates a non-QUIC build, and http3 on; will fail with an unknown-directive error.

  4. Update the TLS-enabled server block with QUIC listeners, the http3 directive, and an Alt-Svc advertisement.
    server {
        listen 443 ssl http2;
        listen [::]:443 ssl http2;
    
        listen 443 quic reuseport;
        listen [::]:443 quic reuseport;
    
        ssl_protocols TLSv1.2 TLSv1.3;
    
        http3 on;
        add_header Alt-Svc 'h3=":443"; ma=86400' always;
    
        ##### snipped #####
    }

    QUIC requires TLS 1.3, and clients cache Alt-Svc for ma seconds, so a small value (for example ma=60) is safer during rollout.

  5. Test the updated configuration for syntax and directive support.
    $ sudo nginx -t
    nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
    nginx: configuration file /etc/nginx/nginx.conf test is successful
  6. Reload Nginx to apply the configuration change.
    $ sudo systemctl reload nginx
  7. Confirm Nginx is listening on UDP 443 for QUIC.
    $ sudo ss --udp --listening --numeric --processes 'sport = :443'
    State  Recv-Q Send-Q Local Address:Port Peer Address:Port Process
    UNCONN 0      0      0.0.0.0:443      0.0.0.0:*     users:(("nginx",pid=1324,fd=6))
    UNCONN 0      0         [::]:443         [::]:*     users:(("nginx",pid=1324,fd=7))
  8. Allow inbound UDP 443 through the firewall path to the server.

    On UFW:

    $ sudo ufw allow 443/udp
    Rule added


    On firewalld:

    $ sudo firewall-cmd --permanent --add-port=443/udp
    success
    $ sudo firewall-cmd --reload
    success


    Cloud security groups and load balancers commonly require a separate rule for 443/udp.

  9. Verify the Alt-Svc header is present on an HTTPS (TCP) response.
    $ curl --head https://example.com
    HTTP/2 200
    server: nginx
    alt-svc: h3=":443"; ma=86400
    ##### snipped #####
  10. Verify HTTP/3 negotiation using an HTTP/3-capable client.
    $ curl --head --http3-only https://example.com
    HTTP/3 200
    server: nginx
    ##### snipped #####

    If --http3-only is rejected as an unknown option, the installed curl build lacks HTTP/3 support.

Discuss the article:

Comment anonymously. Login not required.