Aprire una connessione non è gratis. TCP costa un'andata e ritorno, TLS un'altra, e solo dopo parte la richiesta. Su un collegamento da 60 ms sono 120 ms spesi prima che al tuo server sia stato chiesto alcunché — e per ogni connessione.

Keep-alive vuol dire: fallo una volta sola

Con il keep-alive il browser riusa la stessa connessione per i venti file successivi. È attivo per impostazione predefinita su ogni server moderno, ed è per questo che quest'articolo parla soprattutto di come non romperlo.

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

Verifica di averlo

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

HTTP/2 o HTTP/3 nella riga di stato significa che il riuso della connessione sta già avvenendo e non è qualcosa da configurare — vedi HTTP/2 e HTTP/3. Quello su cui indagare è semmai un Connection: close in una risposta HTTP/1.1.

Le tre cose che lo rompono

  • Un vecchio bilanciatore o proxy davanti che chiude le connessioni per conto suo.
  • Un blocco upstream configurato male — Nginx che parla con la tua applicazione senza un pool keepalive.
  • Servire le risorse da molti nomi host diversi, così che per il file successivo non venga riusata nessuna connessione.
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
}
Servire font, immagini e script dal tuo stesso dominio oggi è più veloce che da un host di terze parti: stessa connessione, nessun DNS in più, nessun TLS in più. Spargere le risorse su più nomi host era un consiglio per HTTP/1.1, e oggi è un costo.