Docs / Web Servers / Enable HTTP/3 and QUIC with Nginx

Enable HTTP/3 and QUIC with Nginx

By Admin · Mar 15, 2026 · Updated Apr 25, 2026 · 129 views · 3 min read

HTTP/3 uses QUIC (UDP-based transport) instead of TCP, offering faster connections, better performance on lossy networks, and built-in encryption. Nginx added HTTP/3 support in version 1.25+. This guide covers enabling HTTP/3 on your VPS for faster web delivery.

Prerequisites

# Check Nginx version (need 1.25.0+)
nginx -v

# Check if built with HTTP/3 support
nginx -V 2>&1 | grep -o "http_v3_module"

# If not, install or build Nginx with QUIC/HTTP3
# Ubuntu 24.04+ includes HTTP/3 support in the mainline package
sudo apt install nginx  # or nginx-mainline

# Or build from source with HTTP/3
wget https://nginx.org/download/nginx-1.27.0.tar.gz
tar xzf nginx-1.27.0.tar.gz
cd nginx-1.27.0
./configure --with-http_v3_module --with-stream_quic_module --with-cc-opt="-I/usr/include/openssl"
make && sudo make install

Configure HTTP/3

server {
    # HTTP/2 over TCP (standard HTTPS)
    listen 443 ssl;
    listen [::]:443 ssl;
    http2 on;

    # HTTP/3 over QUIC (UDP)
    listen 443 quic reuseport;
    listen [::]:443 quic reuseport;

    server_name example.com;

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

    # TLS 1.3 required for HTTP/3
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers off;

    # QUIC settings
    ssl_early_data on;                    # 0-RTT
    quic_retry on;                        # Address validation
    quic_gso on;                          # Generic Segmentation Offload

    # Tell browsers that HTTP/3 is available
    add_header Alt-Svc 'h3=":443"; ma=86400' always;

    # QUIC transport parameters
    # quic_active_connection_id_limit 2;

    location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

Firewall Configuration

# QUIC uses UDP port 443 — must be open!
sudo ufw allow 443/tcp  # HTTPS (HTTP/2)
sudo ufw allow 443/udp  # QUIC (HTTP/3)

# iptables
sudo iptables -A INPUT -p udp --dport 443 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 443 -j ACCEPT

Verify HTTP/3

# Using curl (requires HTTP/3 support)
curl --http3 -I https://example.com
# Look for: HTTP/3 200

# Or check Alt-Svc header (HTTP/2 response tells browser to try HTTP/3)
curl -sI https://example.com | grep alt-svc
# Should show: alt-svc: h3=":443"; ma=86400

# Online tools:
# https://http3check.net
# https://www.http3.dev

# Chrome DevTools: Network tab > Protocol column shows "h3"

0-RTT (Early Data)

# 0-RTT allows sending data with the first packet (no round-trip wait)
# Already enabled with: ssl_early_data on;

# WARNING: 0-RTT is vulnerable to replay attacks
# Protect sensitive endpoints:
location /api/payment {
    # Reject 0-RTT for state-changing operations
    if ($ssl_early_data) {
        return 425;  # Too Early
    }
    proxy_pass http://backend;
}

Performance Benefits

  • Faster initial connection: 1-RTT (or 0-RTT for repeat visits) vs TCP's 3-way handshake + TLS
  • No head-of-line blocking: Lost packets on one stream don't block other streams
  • Connection migration: Connections survive network changes (Wi-Fi to cellular)
  • Better on lossy networks: Significantly faster on mobile and high-latency connections

Best Practices

  • Always keep HTTP/2 as fallback: Not all clients support HTTP/3 yet
  • Open UDP 443: The most common mistake — QUIC uses UDP, not TCP
  • Use reuseport on the QUIC listener for better multi-core performance
  • Enable quic_retry for address validation and DDoS protection
  • Set the Alt-Svc header so browsers discover HTTP/3 availability
  • Protect against 0-RTT replay on state-changing API endpoints

Was this article helpful?