[{"data":1,"prerenderedAt":731},["ShallowReactive",2],{"switcher-blog-pareja":3,"art-nginx-http3-quic-2026-es":6},{"es":4,"en":5},"\u002Fes\u002Fblog\u002Fnginx-http3-quic-2026\u002F","\u002Fen\u002Fblog\u002Fnginx-http3-quic-2026\u002F",{"id":7,"title":8,"author":9,"body":10,"date":717,"description":718,"extension":719,"image":720,"meta":721,"navigation":282,"pareja":722,"path":723,"seo":724,"stem":725,"tags":726,"__hash__":730},"blogEs\u002Fes\u002Fblog\u002Fnginx-http3-quic-2026.md","Nginx con HTTP\u002F3 y QUIC en 2026: cuándo activarlo y cuándo no merece la pena","Paco Cubel",{"type":11,"value":12,"toc":702},"minimark",[13,18,32,47,50,54,57,85,92,104,108,115,126,132,147,151,156,218,236,240,243,394,397,429,433,436,485,492,496,524,527,546,564,576,580,583,616,619,623,662,666,673,676,680,698],[14,15,17],"h2",{"id":16},"el-protocolo-que-llevaba-años-en-experimental","El protocolo que llevaba años en \"experimental\"",[19,20,21,22,26,27,31],"p",{},"Hace dos años, cuando un cliente preguntaba si podíamos activar HTTP\u002F3 en su Nginx, la respuesta honesta era \"podemos, pero no lo recomendamos para producción\". El módulo ",[23,24,25],"code",{},"ngx_http_v3_module"," aterrizó en Nginx 1.25.0 en junio de 2023 marcado como ",[28,29,30],"strong",{},"experimental",", y eso quería decir lo que solía querer decir: funciona en demos y rompe en cosas concretas que no te apetece descubrir un martes por la tarde.",[19,33,34,35,38,39,42,43,46],{},"En 2026 la conversación ha cambiado. Con ",[28,36,37],{},"Nginx 1.26.x"," y ",[28,40,41],{},"OpenSSL 3.5.x o BoringSSL\u002Fquiche",", HTTP\u002F3 sobre QUIC se considera ",[28,44,45],{},"production-ready"," en el sentido en el que se usa la palabra entre administradores de sistemas: lo activas, lo monitorizas un par de semanas y dejas de pensar en ello.",[19,48,49],{},"Vamos a ver cuándo merece la pena la mudanza, cómo se hace y qué cosas siguen pinchando.",[14,51,53],{"id":52},"qué-te-llevas-con-http3-en-una-página","Qué te llevas con HTTP\u002F3 (en una página)",[19,55,56],{},"QUIC reemplaza a TCP por debajo y reescribe el contrato con la red:",[58,59,60,67,73,79],"ul",{},[61,62,63,66],"li",{},[28,64,65],{},"Conexión en 1-RTT"," (o 0-RTT en reconexión). Frente a TCP + TLS, que pide tres apretones de mano para servir el primer byte.",[61,68,69,72],{},[28,70,71],{},"Sin head-of-line blocking entre streams",": si se pierde un paquete que afecta a la imagen del logo, el HTML del artículo no se queda esperando.",[61,74,75,78],{},[28,76,77],{},"Migración de conexión transparente",": el móvil cambia de Wi-Fi a 4G y la sesión TLS no se rompe. Igual que pasaba con HTTP\u002F2 corriendo sobre TCP… excepto que con TCP esa migración nunca funcionó del todo.",[61,80,81,84],{},[28,82,83],{},"Cifrado por defecto",": QUIC no permite tráfico en claro. Suena obvio en 2026, pero impone una higiene de certificados que muchos servidores no tienen.",[19,86,87,88,91],{},"Lo que ",[28,89,90],{},"no"," te lleva HTTP\u002F3:",[58,93,94,97],{},[61,95,96],{},"No es magia para sites lentos en backend. Si el cuello de botella está en PHP-FPM o en la base de datos, HTTP\u002F3 no toca esa parte.",[61,98,99,100,103],{},"No te quita HTTP\u002F2. De hecho, lo recomendable es servir ",[28,101,102],{},"los dos",": HTTP\u002F2 sobre TCP\u002F443 y HTTP\u002F3 sobre UDP\u002F443, y dejar que el cliente negocie.",[14,105,107],{"id":106},"cuándo-activarlo-y-cuándo-seguir-con-http2","Cuándo activarlo (y cuándo seguir con HTTP\u002F2)",[19,109,110,111,114],{},"Activarlo ",[28,112,113],{},"sí"," merece la pena cuando:",[58,116,117,120,123],{},[61,118,119],{},"Tienes tráfico móvil significativo. Es el escenario donde QUIC marca diferencia visible en métricas reales.",[61,121,122],{},"Sirves un sitio internacional con clientes en redes inestables.",[61,124,125],{},"Tu Core Web Vitals está justo al borde y necesitas arañar décimas en LCP\u002FINP.",[19,127,110,128,131],{},[28,129,130],{},"NO"," merece la pena si:",[58,133,134,141,144],{},[61,135,136,137,140],{},"El servidor es una VPS chiquita con poco margen de CPU. QUIC saca trabajo del kernel (TCP) y lo mete en espacio de usuario (QUIC). La factura computacional es real: en cargas altas, Nginx hace ",[28,138,139],{},"más trabajo"," sirviendo HTTP\u002F3 que HTTP\u002F2 para el mismo número de peticiones.",[61,142,143],{},"Tienes un firewall corporativo intermedio que filtra UDP\u002F443. Sí, pasa más de lo que parece — sobre todo en redes empresariales con SD-WAN sin actualizar.",[61,145,146],{},"Tu CDN delante ya hace HTTP\u002F3 hasta el cliente. En ese caso el HTTP\u002F2 origen-CDN no necesita upgrade.",[14,148,150],{"id":149},"activarlo-paso-a-paso","Activarlo paso a paso",[152,153,155],"h3",{"id":154},"_1-verificar-versiones","1. Verificar versiones",[157,158,163],"pre",{"className":159,"code":160,"language":161,"meta":162,"style":162},"language-bash shiki shiki-themes github-light github-dark","nginx -V 2>&1 | grep -oE 'OpenSSL [0-9.]+'   # OpenSSL 3.5.1 o superior\nnginx -V 2>&1 | grep ngx_http_v3              # debe aparecer\n","bash","",[23,164,165,199],{"__ignoreMap":162},[166,167,170,174,178,182,185,188,191,195],"span",{"class":168,"line":169},"line",1,[166,171,173],{"class":172},"sScJk","nginx",[166,175,177],{"class":176},"sj4cs"," -V",[166,179,181],{"class":180},"szBVR"," 2>&1",[166,183,184],{"class":180}," |",[166,186,187],{"class":172}," grep",[166,189,190],{"class":176}," -oE",[166,192,194],{"class":193},"sZZnC"," 'OpenSSL [0-9.]+'",[166,196,198],{"class":197},"sJ8bj","   # OpenSSL 3.5.1 o superior\n",[166,200,202,204,206,208,210,212,215],{"class":168,"line":201},2,[166,203,173],{"class":172},[166,205,177],{"class":176},[166,207,181],{"class":180},[166,209,184],{"class":180},[166,211,187],{"class":172},[166,213,214],{"class":193}," ngx_http_v3",[166,216,217],{"class":197},"              # debe aparecer\n",[19,219,220,221,223,224,227,228,231,232,235],{},"Si no aparece ",[23,222,25],{},", tu paquete no se compiló con HTTP\u002F3. En Debian 13 viene desde el paquete oficial; en Ubuntu 24.04 LTS hay que tirar de PPA oficial de Nginx (",[23,225,226],{},"nginx.org\u002Fpackages\u002Fubuntu",") o recompilar. ",[28,229,230],{},"Ojo",": la versión que viene en ",[23,233,234],{},"apt"," de Ubuntu 22.04 todavía no incluye el módulo en muchos repos derivados.",[152,237,239],{"id":238},"_2-configurar-el-server-block","2. Configurar el server block",[19,241,242],{},"Bloque mínimo funcional para un dominio con TLS ya servido:",[157,244,247],{"className":245,"code":246,"language":173,"meta":162,"style":162},"language-nginx shiki shiki-themes github-light github-dark","server {\n    # HTTP\u002F2 sobre TCP (mantener)\n    listen 443 ssl;\n    listen [::]:443 ssl;\n    http2 on;\n\n    # HTTP\u002F3 sobre QUIC\n    listen 443 quic reuseport;\n    listen [::]:443 quic reuseport;\n    http3 on;\n    http3_hq off;\n\n    # Anunciar disponibilidad de HTTP\u002F3 al cliente\n    add_header Alt-Svc 'h3=\":443\"; ma=86400' always;\n\n    server_name www.miweb.es miweb.es;\n\n    ssl_certificate     \u002Fetc\u002Fletsencrypt\u002Flive\u002Fmiweb.es\u002Ffullchain.pem;\n    ssl_certificate_key \u002Fetc\u002Fletsencrypt\u002Flive\u002Fmiweb.es\u002Fprivkey.pem;\n    ssl_protocols       TLSv1.3;       # QUIC requiere TLS 1.3\n    ssl_early_data on;                  # opcional, habilita 0-RTT\n\n    root \u002Fvar\u002Fwww\u002Fmiweb;\n    index index.html;\n}\n",[23,248,249,254,259,265,271,277,284,290,296,302,308,314,319,325,331,336,342,347,353,359,365,371,376,382,388],{"__ignoreMap":162},[166,250,251],{"class":168,"line":169},[166,252,253],{},"server {\n",[166,255,256],{"class":168,"line":201},[166,257,258],{},"    # HTTP\u002F2 sobre TCP (mantener)\n",[166,260,262],{"class":168,"line":261},3,[166,263,264],{},"    listen 443 ssl;\n",[166,266,268],{"class":168,"line":267},4,[166,269,270],{},"    listen [::]:443 ssl;\n",[166,272,274],{"class":168,"line":273},5,[166,275,276],{},"    http2 on;\n",[166,278,280],{"class":168,"line":279},6,[166,281,283],{"emptyLinePlaceholder":282},true,"\n",[166,285,287],{"class":168,"line":286},7,[166,288,289],{},"    # HTTP\u002F3 sobre QUIC\n",[166,291,293],{"class":168,"line":292},8,[166,294,295],{},"    listen 443 quic reuseport;\n",[166,297,299],{"class":168,"line":298},9,[166,300,301],{},"    listen [::]:443 quic reuseport;\n",[166,303,305],{"class":168,"line":304},10,[166,306,307],{},"    http3 on;\n",[166,309,311],{"class":168,"line":310},11,[166,312,313],{},"    http3_hq off;\n",[166,315,317],{"class":168,"line":316},12,[166,318,283],{"emptyLinePlaceholder":282},[166,320,322],{"class":168,"line":321},13,[166,323,324],{},"    # Anunciar disponibilidad de HTTP\u002F3 al cliente\n",[166,326,328],{"class":168,"line":327},14,[166,329,330],{},"    add_header Alt-Svc 'h3=\":443\"; ma=86400' always;\n",[166,332,334],{"class":168,"line":333},15,[166,335,283],{"emptyLinePlaceholder":282},[166,337,339],{"class":168,"line":338},16,[166,340,341],{},"    server_name www.miweb.es miweb.es;\n",[166,343,345],{"class":168,"line":344},17,[166,346,283],{"emptyLinePlaceholder":282},[166,348,350],{"class":168,"line":349},18,[166,351,352],{},"    ssl_certificate     \u002Fetc\u002Fletsencrypt\u002Flive\u002Fmiweb.es\u002Ffullchain.pem;\n",[166,354,356],{"class":168,"line":355},19,[166,357,358],{},"    ssl_certificate_key \u002Fetc\u002Fletsencrypt\u002Flive\u002Fmiweb.es\u002Fprivkey.pem;\n",[166,360,362],{"class":168,"line":361},20,[166,363,364],{},"    ssl_protocols       TLSv1.3;       # QUIC requiere TLS 1.3\n",[166,366,368],{"class":168,"line":367},21,[166,369,370],{},"    ssl_early_data on;                  # opcional, habilita 0-RTT\n",[166,372,374],{"class":168,"line":373},22,[166,375,283],{"emptyLinePlaceholder":282},[166,377,379],{"class":168,"line":378},23,[166,380,381],{},"    root \u002Fvar\u002Fwww\u002Fmiweb;\n",[166,383,385],{"class":168,"line":384},24,[166,386,387],{},"    index index.html;\n",[166,389,391],{"class":168,"line":390},25,[166,392,393],{},"}\n",[19,395,396],{},"Puntos críticos:",[58,398,399,411,419],{},[61,400,401,406,407,410],{},[28,402,403],{},[23,404,405],{},"reuseport"," solo en el primer ",[23,408,409],{},"listen ... quic",". Sin él, varios workers de Nginx no pueden compartir el mismo puerto UDP eficientemente.",[61,412,413,418],{},[28,414,415],{},[23,416,417],{},"Alt-Svc"," es el mecanismo por el que el navegador descubre que tienes HTTP\u002F3. La primera petición sigue siendo HTTP\u002F2; a partir de la segunda, el navegador prueba QUIC. Sin la cabecera, no pasas a HTTP\u002F3 jamás.",[61,420,421,424,425,428],{},[28,422,423],{},"TLS 1.3 obligatorio",". Si tu config tiene ",[23,426,427],{},"TLSv1.2"," activo solo para HTTP\u002F2, está bien — QUIC ignora esa parte.",[152,430,432],{"id":431},"_3-abrir-el-firewall","3. Abrir el firewall",[19,434,435],{},"Esto se olvida más de lo que parece:",[157,437,439],{"className":159,"code":438,"language":161,"meta":162,"style":162},"sudo ufw allow 443\u002Fudp     # Ubuntu\u002FDebian\nsudo firewall-cmd --permanent --add-port=443\u002Fudp && sudo firewall-cmd --reload  # RHEL family\n",[23,440,441,458],{"__ignoreMap":162},[166,442,443,446,449,452,455],{"class":168,"line":169},[166,444,445],{"class":172},"sudo",[166,447,448],{"class":193}," ufw",[166,450,451],{"class":193}," allow",[166,453,454],{"class":193}," 443\u002Fudp",[166,456,457],{"class":197},"     # Ubuntu\u002FDebian\n",[166,459,460,462,465,468,471,475,477,479,482],{"class":168,"line":201},[166,461,445],{"class":172},[166,463,464],{"class":193}," firewall-cmd",[166,466,467],{"class":176}," --permanent",[166,469,470],{"class":176}," --add-port=443\u002Fudp",[166,472,474],{"class":473},"sVt8B"," && ",[166,476,445],{"class":172},[166,478,464],{"class":193},[166,480,481],{"class":176}," --reload",[166,483,484],{"class":197},"  # RHEL family\n",[19,486,487,488,491],{},"Si estás detrás de un balanceador (HAProxy, AWS NLB, etc.), el balanceador tiene que reenviar UDP\u002F443. Muchos LBs de los proveedores cloud ",[28,489,490],{},"solo balancean TCP por defecto",". Sin abrir UDP\u002F443 en el camino completo, HTTP\u002F3 no llega al servidor.",[152,493,495],{"id":494},"_4-recargar-y-verificar","4. Recargar y verificar",[157,497,499],{"className":159,"code":498,"language":161,"meta":162,"style":162},"sudo nginx -t\nsudo systemctl reload nginx\n",[23,500,501,511],{"__ignoreMap":162},[166,502,503,505,508],{"class":168,"line":169},[166,504,445],{"class":172},[166,506,507],{"class":193}," nginx",[166,509,510],{"class":176}," -t\n",[166,512,513,515,518,521],{"class":168,"line":201},[166,514,445],{"class":172},[166,516,517],{"class":193}," systemctl",[166,519,520],{"class":193}," reload",[166,522,523],{"class":193}," nginx\n",[19,525,526],{},"Test desde fuera:",[157,528,530],{"className":159,"code":529,"language":161,"meta":162,"style":162},"curl --http3 -I https:\u002F\u002Fmiweb.es\n",[23,531,532],{"__ignoreMap":162},[166,533,534,537,540,543],{"class":168,"line":169},[166,535,536],{"class":172},"curl",[166,538,539],{"class":176}," --http3",[166,541,542],{"class":176}," -I",[166,544,545],{"class":193}," https:\u002F\u002Fmiweb.es\n",[19,547,548,549,552,553,556,557,559,560,563],{},"Si ves ",[23,550,551],{},"HTTP\u002F3 200",", va. Si ves ",[23,554,555],{},"HTTP\u002F2 200",", el servidor responde pero el cliente no pidió HTTP\u002F3 (revisa ",[23,558,536],{}," con ",[23,561,562],{},"--http3-only"," para forzar y diagnosticar).",[19,565,566,567,569,570,572,573,575],{},"Test desde navegador: Chrome o Firefox → DevTools → Network → columna \"Protocol\" debe mostrar ",[23,568,152],{}," en la segunda recarga (la primera siempre será ",[23,571,14],{}," por la negociación de ",[23,574,417],{},").",[14,577,579],{"id":578},"casos-en-producción-que-hemos-visto","Casos en producción que hemos visto",[19,581,582],{},"Algunos números reales de los últimos seis meses, sin endulzar:",[58,584,585,592,602,609],{},[61,586,587,588,591],{},"Site de comercio electrónico mediano, ~80% tráfico móvil: ",[28,589,590],{},"LCP -8%"," medido en Chrome UX Report tras activar HTTP\u002F3. Bonito. No revolucionario.",[61,593,594,595,598,599,601],{},"Site corporativo, tráfico mayoritariamente desktop con fibra: ",[28,596,597],{},"diferencia inapreciable",". La negociación ",[23,600,417],{}," añade un par de bytes a la primera respuesta y poco más.",[61,603,604,605,608],{},"Site internacional con clientes en Latinoamérica y África: ",[28,606,607],{},"mejora de 200-400ms en TTFB en redes con latencia alta",". Aquí sí se nota.",[61,610,611,612,615],{},"VPS pequeña (1 vCPU, 2 GB RAM) sirviendo blog estático con picos esporádicos: ",[28,613,614],{},"CPU subió un 6% de media",", sin beneficio visible. Lo volvimos a desactivar.",[19,617,618],{},"Moraleja: medir antes y después, no asumir.",[14,620,622],{"id":621},"cosas-que-siguen-siendo-molestas","Cosas que siguen siendo molestas",[58,624,625,633,639,653],{},[61,626,627,632],{},[28,628,629,631],{},[23,630,405],{}," requiere kernel reciente"," (4.5+). Cualquier servidor con kernel actualizado lo tiene, pero comprueba si estás en una distro antigua.",[61,634,635,638],{},[28,636,637],{},"Algunos CDNs intermedios todavía no hablan HTTP\u002F3 entre origin y edge",". Si tienes Cloudflare delante, el cliente sí ve HTTP\u002F3 (porque lo hace Cloudflare) y el upgrade en origen no aporta nada.",[61,640,641,644,645,648,649,652],{},[28,642,643],{},"Diagnóstico más opaco",": capturar tráfico QUIC no es como capturar TCP. Necesitas Wireshark reciente, ",[23,646,647],{},"SSLKEYLOGFILE"," y paciencia. Si vienes de depurar HTTP\u002F2 con ",[23,650,651],{},"tcpdump",", prepárate.",[61,654,655,658,659,661],{},[28,656,657],{},"Las herramientas legacy (curl viejo, wget, ciertos clientes de monitorización) no hablan HTTP\u002F3",". Asegúrate de que el ",[23,660,417],{}," no rompe tu pipeline de monitorización.",[14,663,665],{"id":664},"lo-activamos-en-tu-servidor","¿Lo activamos en tu servidor?",[19,667,668,669,672],{},"Nuestro consejo en una frase: ",[28,670,671],{},"si tienes tráfico móvil significativo y kernel + Nginx recientes, sí. Si no, espera al siguiente refresco de servidor y hazlo entonces."," No es un cambio que arregle ningún problema; es un cambio que añade margen donde antes no había.",[19,674,675],{},"Si quieres que lo evaluemos para tu caso, hablamos. La activación en sí lleva una hora; la auditoría previa para no romper monitorización ni firewalls, otra. Lo demás es medir.",[14,677,679],{"id":678},"referencias","Referencias",[58,681,682,691],{},[61,683,684],{},[685,686,690],"a",{"href":687,"rel":688},"https:\u002F\u002Fnginx.org\u002Fen\u002Fdocs\u002Fquic.html",[689],"nofollow","Support for QUIC and HTTP\u002F3 — Nginx Documentation",[61,692,693],{},[685,694,697],{"href":695,"rel":696},"https:\u002F\u002Fblog.nginx.org\u002Fblog\u002Four-roadmap-quic-http-3-support-nginx",[689],"Our Roadmap for QUIC and HTTP\u002F3 Support in NGINX — NGINX Community Blog",[699,700,701],"style",{},"html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}",{"title":162,"searchDepth":201,"depth":201,"links":703},[704,705,706,707,713,714,715,716],{"id":16,"depth":201,"text":17},{"id":52,"depth":201,"text":53},{"id":106,"depth":201,"text":107},{"id":149,"depth":201,"text":150,"children":708},[709,710,711,712],{"id":154,"depth":261,"text":155},{"id":238,"depth":261,"text":239},{"id":431,"depth":261,"text":432},{"id":494,"depth":261,"text":495},{"id":578,"depth":201,"text":579},{"id":621,"depth":201,"text":622},{"id":664,"depth":201,"text":665},{"id":678,"depth":201,"text":679},"2026-05-26","HTTP\u002F3 sobre QUIC ya es producción en Nginx 1.26.x. Te contamos cómo activarlo paso a paso, qué ganas de verdad y en qué casos seguir con HTTP\u002F2 sigue siendo la opción inteligente.","md","\u002Fog\u002Fog-default.png",{},"nginx-http3-quic-2026","\u002Fes\u002Fblog\u002Fnginx-http3-quic-2026",{"title":8,"description":718},"es\u002Fblog\u002Fnginx-http3-quic-2026",[727,728,729],"Servidores","Nginx","Rendimiento","L4EBIamSVmT1gwBUuGJMT_UHgMMmMoF-F4UQghaIyJ8",1781154907658]