Dominando QUIC y HTTP/3 con Nginx: La Guía Completa
Inmersión profunda en QUIC y HTTP/3 — arquitectura técnica, seguridad y configuración paso a paso de Nginx para despliegue en producción.

La web ha dependido de TCP durante más de cuatro décadas. Pero las aplicaciones modernas —con sus exigencias de interactividad en tiempo real, conectividad móvil y cargas de página instantáneas— han expuesto las limitaciones fundamentales de TCP. Llegan QUIC y HTTP/3: una reinvención completa del transporte web que abandona TCP en favor de UDP para ofrecer un internet más rápido, seguro y resiliente.
En esta guía completa, exploraremos la historia y la arquitectura de QUIC, entenderemos por qué resuelve problemas que TCP no puede, y recorreremos una configuración completa de Nginx lista para producción.
TL;DR — QUIC y HTTP/3 en Nginx
6 puntos clave- QUIC funciona sobre UDP, no TCP: HTTP/3 mapea la semántica HTTP sobre QUIC, que se construye sobre UDP y exige TLS 1.3.
- Resuelve el HOL blocking: los streams de QUIC son independientes en la capa de transporte, así que un paquete perdido solo bloquea su propio stream, no todos los streams multiplexados como en HTTP/2 sobre TCP.
- Handshakes más rápidos y migración de conexión: handshake combinado de transporte+criptografía (1-RTT, o 0-RTT al reanudar) más Connection IDs que sobreviven a los cambios de red (Wi-Fi → datos móviles).
- Nginx necesita 1.25.0+ con
--with-http_v3_moduley una biblioteca SSL con soporte QUIC (OpenSSL 3.5.1+, BoringSSL, QuicTLS o LibreSSL 3.6+). - Configuración base: añade
listen 443 quic reuseport;, activahttp3 on, TLS 1.3 y la cabeceraAlt-Svc;reuseportdebe aparecer en exactamente un listener por dirección:puerto. - Abre UDP/443 en el firewall (servidor y proveedor cloud) o QUIC fallará silenciosamente y los clientes retrocederán a HTTP/2; verifica con
curl --http3, las DevTools oquic="h3"en el log de acceso.
Breve historia: de Google al estándar IETF
El protocolo QUIC tiene una evolución interesante desde un experimento propietario de Google hasta un estándar IETF completo.
| Año | Hito | Importancia |
|---|---|---|
| 2012 | Google comienza el desarrollo de QUIC | Proyecto interno para reducir la latencia web |
| 2013 | Primer tráfico QUIC en Chrome | Primeros experimentos con servicios de Google |
| 2014 | Despliegue a gran escala de gQUIC | Chrome de escritorio usa QUIC para las propiedades de Google |
| 2016 | Se forma el Grupo de Trabajo QUIC del IETF | Comienza el proceso de estandarización formal |
| 2017 | IETF QUIC diverge de gQUIC | Integración de TLS 1.3, transporte de propósito general |
| 2021 | Se publica el RFC 9000 | Protocolo de transporte QUIC estandarizado |
| 2022 | Se publica el RFC 9114 | HTTP/3 estandarizado |
La familia de RFCs de QUIC
La especificación completa de QUIC abarca múltiples RFCs:
| RFC | Título | Descripción |
|---|---|---|
| RFC 9000 | QUIC Transport | Protocolo base: paquetes, frames, streams, gestión de conexiones |
| RFC 9001 | Using TLS to Secure QUIC | Integración de TLS 1.3, derivación de claves, niveles de cifrado |
| RFC 9002 | Loss Detection and Congestion Control | Recuperación de paquetes perdidos, estimación de RTT, algoritmos de congestión |
| RFC 8999 | Version-Independent Properties | Comportamientos comunes a todas las versiones de QUIC |
| RFC 9114 | HTTP/3 | Semántica HTTP sobre QUIC |
¿Por qué QUIC? Entendiendo las limitaciones de TCP
Para apreciar QUIC, debemos entender por qué TCP —la columna vertebral de internet desde 1974— tiene dificultades con las demandas modernas de la web.
El problema del head-of-line (HOL) blocking
Este es el problema fundamental que QUIC resuelve. Imagina una autopista con un solo carril (conexión TCP). Si un coche se avería (pérdida de paquete), todos los que van detrás deben parar y esperar, aunque vayan a destinos diferentes.
El problema de la latencia del handshake
Establecer una conexión TCP segura requiere múltiples viajes de ida y vuelta:
| Protocolo | Conexión nueva | Conexión reanudada | RTTs totales |
|---|---|---|---|
| TCP + TLS 1.2 | TCP handshake + TLS handshake | TCP + TLS abreviado | 3 RTT → 2 RTT |
| TCP + TLS 1.3 | TCP handshake + TLS 1.3 | TCP + TLS 0-RTT | 2 RTT → 1 RTT |
| QUIC | Handshake combinado | 0-RTT early data | 1 RTT → 0 RTT |
El problema de la migración de conexión
Las conexiones TCP se identifican por una 4-tupla: (IP origen, puerto origen, IP destino, puerto destino). Cuando cambias de Wi-Fi a datos móviles, tu IP cambia — y tu conexión TCP se rompe.
Arquitectura de QUIC en profundidad
Transporte sobre UDP
QUIC se construye sobre UDP en lugar de crear un nuevo protocolo IP. Fue una elección pragmática:
- No requiere cambios en el kernel: UDP tiene soporte universal
- Implementación en espacio de usuario: Iteración y despliegue más rápidos
- Traversal de middleboxes: UDP atraviesa la mayoría de NATs y firewalls
Estructura de paquetes
QUIC utiliza dos tipos de paquetes:
| Tipo | Cabecera | Uso | Cifrado |
|---|---|---|---|
| Long Header | Información completa de conexión | Initial, Handshake, 0-RTT, Retry | Claves específicas por nivel |
| Short Header | Mínima (post-handshake) | Datos de aplicación (1-RTT) | Claves de aplicación |
Streams y control de flujo
Los streams QUIC son canales ligeros y multiplexados dentro de una conexión:
Decodificación del Stream ID: El Stream ID es un entero de 62 bits donde los 2 bits menos significativos funcionan como cabecera de tipo:
- Bit 0 (Iniciador):
0= Cliente,1= Servidor - Bit 1 (Dirección):
0= Bidireccional,1= Unidireccional
Esto crea 4 espacios de direcciones distintos:
- …00: Petición/Respuesta del cliente
- …01: Server Push (obsoleto)
- …10: Stream de control del cliente
- …11: Stream de control del servidor (QPACK)
Control de flujo de doble capa: Para que un paquete sea procesado, debe pasar dos comprobaciones independientes:
- Nivel de conexión: ¿Hay crédito
MAX_DATApara toda la conexión? - Nivel de stream: ¿Hay crédito
MAX_STREAM_DATApara este stream específico? Si cualquiera se agota, la transmisión se bloquea hasta que llegue un frameWINDOW_UPDATE.
El handshake de QUIC: velocidad y seguridad
QUIC combina los handshakes de transporte y criptográficos en un único intercambio, reduciendo drásticamente la latencia.
Handshake 1-RTT (primera conexión)
Handshake 0-RTT (conexión reanudada)
Para clientes que se han conectado previamente, QUIC permite enviar datos cifrados en el primer paquete:
Arquitectura de seguridad
La seguridad de QUIC no es opcional —está integrada en el protocolo desde su diseño.
Cuatro niveles de cifrado
| Nivel | Claves derivadas de | Uso | Forward Secrecy |
|---|---|---|---|
| Initial | Destination Connection ID | Primeros paquetes, negociación de versión | No |
| 0-RTT | Clave precompartida (PSK) | Datos de aplicación tempranos | No |
| Handshake | Secretos del handshake TLS | Completar el handshake | Parcial |
| Application (1-RTT) | Secretos de tráfico TLS | Todos los datos post-handshake | Completo (ECDHE) |
Protección de paquetes
Cada paquete QUIC (excepto Initial) está protegido con cifrado AEAD:
| Sección del paquete | Componente | Nivel de protección |
|---|---|---|
| Cabecera | Flags | Protegido (Header Protection) |
| Connection ID | Texto claro (para enrutamiento) | |
| Número de paquete | Cifrado (Header Protection) | |
| Carga útil | Datos de aplicación | Totalmente cifrado (AEAD) |
| Pie | Etiqueta de autenticación | MAC de integridad de 16 bytes |
Connection ID y privacidad
Mecanismos de protección contra DoS
QUIC incluye varias medidas anti-amplificación y anti-suplantación:
- Validación de dirección: Los servidores envían paquetes
RETRYpara validar las direcciones de los clientes - Anti-amplificación: Los servidores limitan los datos enviados antes de la validación de dirección (3x los datos del cliente)
- Stateless Reset: Terminación limpia de conexión sin estado
HTTP/3: HTTP sobre QUIC
HTTP/3 es el mapeo de la semántica HTTP sobre el transporte QUIC. Reemplaza el framing binario de HTTP/2 con streams QUIC.
| Característica | HTTP/2 | HTTP/3 |
|---|---|---|
| Transporte | TCP + TLS | QUIC (UDP + TLS 1.3) |
| Multiplexing | Frames de stream en una única conexión | Streams nativos de QUIC |
| HOL Blocking | Sí (en la capa TCP) | No (streams independientes) |
| Compresión de cabeceras | HPACK | QPACK (maneja el desorden) |
| Server Push | Soportado | Obsoleto (poco usado) |
| Migración de conexión | No | Sí |
Adopción actual
A fecha de 2026, la adopción de HTTP/3 es significativa y creciente:
| Métrica | Valor | Fuente |
|---|---|---|
| Sitios web usando HTTP/3 | 36,6% | W3Techs (2026) |
| Uso de QUIC en Chrome (subsiguiente) | 40% | APNIC Labs |
| Mejora en carga de página (global) | 12,4% | Cloudflare Benchmarks |
| Mejora en regiones de alta latencia | 13,8% | DebugBear |
Configuración de Nginx: guía completa
Ahora vamos a implementar HTTP/3 en Nginx. Esta sección cubre todo, desde los prerrequisitos hasta el despliegue en producción.
Prerrequisitos
Verifica tu instalación de Nginx:
nginx version: nginx/1.28.0 built with OpenSSL 3.5.0 8 Apr 2025 (running with OpenSSL 3.5.4 30 Sep 2025) configure arguments: … —with-http_v3_module …
Cómo instalar Nginx con soporte HTTP/3
Este repositorio (ampliamente usado para PHP y Nginx) proporciona las últimas versiones mainline con soporte HTTP/3 y muchos módulos adicionales para Debian y Ubuntu.
# Para Debian:
sudo apt install curl gpg
curl -fsSL https://packages.sury.org/nginx/README.txt | sudo bash -x
# Para Ubuntu:
sudo add-apt-repository ppa:ondrej/nginx-mainline
sudo apt update
# Instalar Nginx:
sudo apt install nginx# Add official Nginx mainline repository
sudo apt install curl gnupg2 ca-certificates lsb-release
# Create keyring directory if it doesn't exist
sudo mkdir -p /etc/apt/keyrings
# Download and add the Nginx signing key (modern approach)
curl -fsSL https://nginx.org/keys/nginx_signing.key \
| sudo gpg --dearmor -o /etc/apt/keyrings/nginx.gpg
# Add repository with signed-by keyring
echo "deb [signed-by=/etc/apt/keyrings/nginx.gpg] http://nginx.org/packages/mainline/ubuntu $(lsb_release -cs) nginx" \
| sudo tee /etc/apt/sources.list.d/nginx.list
sudo apt update
sudo apt install nginx# Download Nginx and QuicTLS
wget https://nginx.org/download/nginx-1.25.3.tar.gz
git clone --depth 1 https://github.com/quictls/openssl quictls
# Build QuicTLS
cd quictls
./Configure --prefix=$PWD/build linux-x86_64
make -j$(nproc)
make install_sw
cd ..
# Configure and build Nginx
tar xzf nginx-1.25.3.tar.gz
cd nginx-1.25.3
./configure \
--with-http_v3_module \
--with-http_ssl_module \
--with-http_v2_module \
--with-cc-opt="-I../quictls/build/include" \
--with-ld-opt="-L../quictls/build/lib"
make -j$(nproc)
sudo make installConfiguración básica
Esta es la configuración mínima para habilitar HTTP/3:
server {
server_name example.com;
root /var/www/example.com;
# ==========================================
# LISTENERS: TCP (HTTP/1.1, HTTP/2) + UDP (HTTP/3)
# ==========================================
# Standard HTTPS over TCP
listen 443 ssl;
listen [::]:443 ssl;
http2 on;
# QUIC/HTTP/3 over UDP
# 'reuseport' is critical for multi-worker performance
listen 443 quic reuseport;
listen [::]:443 quic reuseport;
# ==========================================
# SSL/TLS CONFIGURATION
# ==========================================
# TLS 1.3 is REQUIRED for QUIC
ssl_protocols TLSv1.3 TLSv1.2;
ssl_prefer_server_ciphers off;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
# ==========================================
# HTTP/3 CONFIGURATION
# ==========================================
http3 on;
# Advertise HTTP/3 support to browsers
# ma=86400 means "cache this info for 24 hours"
add_header Alt-Svc 'h3=":443"; ma=86400' always;
location / {
try_files $uri $uri/ =404;
}
}Configuración completa de producción
Aquí tienes una configuración exhaustiva con todas las optimizaciones. La configuración se divide en dos archivos: el nginx.conf principal para ajustes globales y un archivo de configuración específico del sitio.
/etc/nginx/nginx.conf
# Main context
worker_processes auto;
error_log /var/log/nginx/error.log warn;
events {
worker_connections 4096;
use epoll;
multi_accept on;
}
http {
# ==========================================
# HTTP/3 GLOBAL SETTINGS
# ==========================================
# Explicit for clarity (http3 defaults to 'on' in nginx 1.25.0+)
http3 on;
# Custom log format to track HTTP/3 connections
log_format quic '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'proto="$server_protocol" quic="$http3"';
# MIME types
include /etc/nginx/mime.types;
default_type application/octet-stream;
# Performance optimizations
sendfile on;
tcp_nopush on;
tcp_nodelay on;
# Gzip compression
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_types text/plain text/css application/json application/javascript
text/xml application/xml application/xml+rss text/javascript;
# Include site configurations
include /etc/nginx/sites-enabled/*;
}La configuración específica del sitio incluye todas las directivas para QUIC, TLS, cabeceras y logging:
/etc/nginx/sites-available/example.com.conf
server {
server_name example.com www.example.com;
root /var/www/example.com;
# ==========================================
# DUAL-STACK LISTENERS
# ==========================================
# TCP: HTTP/1.1 and HTTP/2 fallback
listen 443 ssl;
listen [::]:443 ssl;
http2 on;
# UDP: QUIC/HTTP/3
listen 443 quic reuseport;
listen [::]:443 quic reuseport;
# ==========================================
# TLS CONFIGURATION (Required for QUIC)
# ==========================================
ssl_protocols TLSv1.3 TLSv1.2;
# TLS 1.3 ciphersuites (handled separately for better OpenSSL compatibility)
ssl_conf_command Ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256;
# TLS 1.2 ciphers only (ECDHE for forward secrecy)
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305;
ssl_prefer_server_ciphers off;
ssl_ecdh_curve X25519:P-256:P-384;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
# Session resumption for performance
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
ssl_session_tickets off; # Better security
# OCSP Stapling
ssl_stapling on;
ssl_stapling_verify on;
# ==========================================
# QUIC-SPECIFIC SETTINGS
# ==========================================
# Enable 0-RTT early data (with security considerations)
ssl_early_data on;
# DoS protection: require address validation
quic_retry on;
# Performance: Generic Segmentation Offload (Linux 4.18+)
quic_gso on;
# ==========================================
# HEADERS
# ==========================================
# Advertise HTTP/3 availability
add_header Alt-Svc 'h3=":443"; ma=86400' always;
# Warn backends about 0-RTT replay risk
add_header Early-Data $ssl_early_data always;
# Security headers
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "DENY" always;
# ==========================================
# LOGGING
# ==========================================
access_log /var/log/nginx/example.com.access.log quic;
error_log /var/log/nginx/example.com.error.log;
# ==========================================
# LOCATIONS
# ==========================================
location / {
try_files $uri $uri/ =404;
}
# Static assets with long cache
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2)$ {
expires 1y;
add_header Cache-Control "public, immutable" always;
add_header Alt-Svc 'h3=":443"; ma=86400' always;
# Security headers (inherited from server block may not apply with add_header in location)
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "DENY" always;
}
}
# HTTP to HTTPS redirect
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
return 301 https://$host$request_uri;
}Referencia de todas las directivas QUIC
| Directiva | Por defecto | Contexto | Descripción |
|---|---|---|---|
http3 | on | http, server | Habilita la negociación del protocolo HTTP/3 |
http3_hq | off | http, server | Habilita HTTP/0.9 sobre QUIC (solo para pruebas) |
http3_max_concurrent_streams | 128 | http, server | Máximo de streams concurrentes por conexión |
http3_stream_buffer_size | 64k | http, server | Tamaño del buffer para lectura/escritura de streams |
quic_active_connection_id_limit | 2 | http, server | Máximo de Connection IDs almacenados por conexión |
quic_bpf | off | main | Enrutamiento eBPF para migración de conexión (Linux 5.7+) |
quic_gso | off | http, server | Generic Segmentation Offload (Linux 4.18+) |
quic_host_key | - | http, server | Archivo con clave secreta para tokens de validación de dirección |
quic_retry | off | http, server | Habilita la validación de dirección mediante paquetes Retry |
Configuración del firewall
Crítico: HTTP/3 usa UDP en el puerto 443, no TCP. Si tu firewall solo permite TCP/443, QUIC fallará silenciosamente y los clientes retrocedarán a HTTP/2.
# Check current rules
sudo ufw status
# Allow UDP on port 443
sudo ufw allow 443/udp comment 'QUIC/HTTP3'
# Verify
sudo ufw status verbose# Allow incoming UDP 443
sudo iptables -A INPUT -p udp --dport 443 -j ACCEPT
# Save rules (Debian/Ubuntu)
sudo iptables-save | sudo tee /etc/iptables/rules.v4
# For IPv6
sudo ip6tables -A INPUT -p udp --dport 443 -j ACCEPT
sudo ip6tables-save | sudo tee /etc/iptables/rules.v6# Add UDP 443 to default zone
sudo firewall-cmd --permanent --add-port=443/udp
# Reload
sudo firewall-cmd --reload
# Verify
sudo firewall-cmd --list-portsAñade una regla de entrada:
- Tipo: Custom UDP
- Rango de puertos: 443
- Origen: 0.0.0.0/0 (o tu CIDR)
- Descripción: QUIC/HTTP3
Ajuste del kernel para alto tráfico
Para servidores con alto tráfico, aumenta los tamaños de buffer UDP:
# Increase UDP buffer sizes for QUIC
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.core.rmem_default = 1048576
net.core.wmem_default = 1048576
# UDP memory limits
net.ipv4.udp_mem = 65536 131072 262144
net.ipv4.udp_rmem_min = 8192
net.ipv4.udp_wmem_min = 8192
# Allow more local ports for connections
net.ipv4.ip_local_port_range = 1024 65535Aplica los ajustes:
Verificación y pruebas
Tras la configuración, verifica que HTTP/3 funciona correctamente.
Método 1: curl
Las versiones modernas de curl (7.66+ con soporte HTTP/3) permiten probar directamente:
HTTP/3 200 server: jmrp.io date: Wed, 14 Jan 2026 20:02:32 GMT content-type: text/html; charset=utf-8 alt-svc: h3=“:443”; ma=86400 strict-transport-security: max-age=63072000; includeSubDomains; preload
Método 2: DevTools del navegador
- Abre Chrome o Firefox
- Navega a tu sitio
- Abre DevTools (F12) → pestaña Red (Network)
- Haz clic derecho en las cabeceras de columna → Activa la columna Protocolo
- Recarga la página
- Busca
h3en la columna Protocolo
Método 3: herramientas online
| Herramienta | URL | Características |
|---|---|---|
| HTTP/3 Check | http3check.net | Test rápido de aprobado/suspenso con detalles |
| Cloudflare HTTP/3 Test | cloudflare-quic.com | Prueba de conexión en vivo |
| Qualys SSL Labs | ssllabs.com | Análisis exhaustivo de TLS |
Método 4: comprobar los logs de Nginx
Usa el formato de log personalizado para verificar el tráfico HTTP/3:
192.168.1.100 - - [14/Jan/2026:20:02:32 +0000] “GET / HTTP/3” 200 15234 ”-” “Mozilla/5.0…” proto=“HTTP/3” quic=“h3”
Guía de resolución de problemas
| Síntoma | Causa probable | Solución |
|---|---|---|
| El protocolo se queda en HTTP/2 | Firewall bloqueando UDP/443 | Abre el puerto UDP 443 en el servidor y en el proveedor cloud |
| El protocolo se queda en HTTP/2 | Falta la cabecera Alt-Svc | Añade add_header Alt-Svc ‘h3=“:443”; ma=86400’ always; |
| Errores de conexión | TLS 1.3 no habilitado | Habilita TLSv1.3 para QUIC (obligatorio); TLSv1.2 puede seguir habilitado como fallback para HTTP/2 |
| Los navegadores se niegan a usar QUIC | Certificado autofirmado | Usa un certificado válido (Let’s Encrypt) |
| Nginx no arranca | Falta —with-http_v3_module | Recompila Nginx con el módulo HTTP/3 |
| Uso alto de CPU | GSO no soportado por el kernel | Desactiva quic_gso o actualiza el kernel |
| 0-RTT no funciona | Versión de OpenSSL demasiado antigua | Usa OpenSSL 3.5.1+, QuicTLS o BoringSSL |
Modo depuración
Activa el logging de depuración temporalmente:
error_log /var/log/nginx/error.log debug;Comprueba los mensajes específicos de QUIC:
2026/01/14 10:42:15 [debug] 12345#0: *1 quic handle packet: fd:16, addr:192.0.2.1:54321 2026/01/14 10:42:15 [debug] 12345#0: *1 quic packet rx dcid len:8 87654321 2026/01/14 10:42:15 [debug] 12345#0: *1 quic packet rx scid len:8 12345678 2026/01/14 10:42:15 [info] 12345#0: *1 quic SSL_do_handshake() failed: SSL_ERROR_SSL: error:14094416:SSL routines:ssl3_read_bytes:sslv3 alert certificate unknown 2026/01/14 10:42:15 [debug] 12345#0: *1 quic close connection: 0:
Lista de verificación para producción
Antes de desplegar HTTP/3 en producción, verifica:
| Categoría | Elemento | Verificación |
|---|---|---|
| Build | Nginx compilado con —with-http_v3_module | nginx -V 2>&1 | grep http_v3 |
| Build | Biblioteca SSL compatible (QuicTLS/BoringSSL/OpenSSL 3.5.1+) | nginx -V 2>&1 | grep -i ssl |
| Red | UDP/443 abierto en el firewall del servidor | sudo ss -ulnp | grep 443 |
| Red | UDP/443 abierto en el proveedor cloud (AWS/GCP/Azure) | Comprueba las reglas del security group/firewall |
| Config | listen 443 quic reuseport; presente | nginx -T | grep quic |
| Config | TLS 1.3 habilitado | nginx -T | grep ssl_protocols |
| Config | Cabecera Alt-Svc configurada | curl -I https://site | grep alt-svc |
| Certificado | Certificado válido (no autofirmado) | openssl s_client -connect site:443 |
| Prueba | HTTP/3 confirmado y funcionando | curl —http3 https://site |
| Monitorización | Formato de log incluye $http3 | Comprueba la configuración del formato de log |
Cuándo NO usar QUIC
Aunque QUIC ofrece beneficios significativos, hay escenarios donde TCP puede ser preferible:
Preguntas frecuentes
¿Qué necesito para habilitar HTTP/3 en Nginx?
Necesitas Nginx 1.25.0 o superior (el soporte HTTP/3 se añadió a mediados de 2023) compilado con --with-http_v3_module, además de una biblioteca SSL con soporte QUIC como OpenSSL 3.5.1+, BoringSSL, QuicTLS o LibreSSL 3.6+. TLS 1.3 es obligatorio para QUIC.
¿HTTP/3 usa TCP o UDP?
HTTP/3 funciona sobre QUIC, que se construye sobre UDP en lugar de TCP. Debes abrir el puerto UDP 443 tanto en el firewall del servidor como en el del proveedor cloud, o QUIC fallará silenciosamente y los clientes retrocederán a HTTP/2.
¿Cómo resuelve QUIC el head-of-line blocking de TCP?
TCP ve todo como un único flujo ordenado de bytes, así que un solo paquete perdido bloquea todos los streams multiplexados de HTTP/2 hasta su retransmisión. QUIC implementa streams en la capa de transporte, dando entrega independiente a cada stream, por lo que un paquete perdido solo afecta a su propio stream.
¿Por qué mi navegador sigue mostrando HTTP/2 en la primera visita?
Es normal. En la primera visita los navegadores usan HTTP/2 para descubrir la cabecera Alt-Svc que anuncia HTTP/3; en peticiones posteriores o tras recargar cambian a HTTP/3.
¿Por qué es crítico el flag reuseport para QUIC en Nginx?
UDP no tiene conexión, así que sin reuseport todos los paquetes QUIC los maneja un único worker de Nginx, creando un cuello de botella. La función reuseport del kernel distribuye los paquetes entre los workers, pero debe aparecer en exactamente una directiva listen por dirección:puerto a nivel global o Nginx no arrancará.
¿Cómo verifico que HTTP/3 funciona?
Usa curl moderno con curl -I --http3 https://tusitio, activa la columna Protocolo en las DevTools del navegador y busca h3, usa herramientas online como http3check.net o cloudflare-quic.com, o filtra el log de acceso de Nginx por quic="h3".