Abrir una conexión no sale gratis. TCP cuesta una ida y vuelta, TLS otra, y solo entonces sale la petición. En un enlace de 60 ms son 120 ms gastados antes de que a tu servidor se le haya preguntado nada, y eso por cada conexión.

Keep-alive significa: haz eso una sola vez

Con keep-alive el navegador reutiliza la misma conexión para los veinte archivos siguientes. Viene activado por defecto en cualquier servidor moderno, y por eso este artículo trata sobre todo de no romperlo.

# nginx defaults, and they are sensible
keepalive_timeout 65;
keepalive_requests 1000;

Comprueba que lo tienes

curl -sSI https://yourdomain.com/ | grep -i -E 'connection|http/'

Ver HTTP/2 o HTTP/3 en la línea de estado significa que la reutilización ya está ocurriendo y no es algo que tengas que configurar: consulta HTTP/2 y HTTP/3. Lo que sí conviene investigar es un Connection: close en una respuesta HTTP/1.1.

Las tres cosas que lo rompen

  • Un balanceador o proxy antiguo por delante que cierra las conexiones por su cuenta.
  • Un bloque upstream mal configurado: Nginx hablando con tu aplicación sin un pool de keepalive.
  • Servir los recursos desde muchos nombres de host distintos, de modo que no se reutiliza ninguna conexión para el archivo siguiente.
upstream app {
    server 127.0.0.1:9000;
    keepalive 32;          # the pool Nginx keeps open to your app
}

location / {
    proxy_http_version 1.1;
    proxy_set_header Connection "";   # required, or the pool is not used
}
Servir tipografías, imágenes y scripts desde tu propio dominio es hoy más rápido que desde un servidor ajeno: la misma conexión, sin DNS de más, sin TLS de más. Repartir los recursos entre varios nombres de host era un consejo para HTTP/1.1 y hoy es un coste.