Perché il TLS handshake è ancora il vostro nemico nascosto del TTFB
Il 95% del traffico web oggi viaggia su HTTPS, ma la maggior parte delle configurazioni Nginx in produzione usa ancora i parametri di default che erano ragionevoli cinque anni fa e oggi lasciano sul tavolo decine di millisecondi di Time To First Byte. La buona notizia è che si tratta quasi sempre di ottimizzazioni “una tantum”: si toccano poche direttive, si ricarica Nginx e il guadagno resta lì, per ogni richiesta, per sempre.
In questo articolo vediamo come intervenire su cache di sessione, cifrari, buffer TLS, HTTP/3 e header di sicurezza, con un occhio a cosa è cambiato di recente (OCSP stapling è ormai carta straccia con Let’s Encrypt, HTTP/3 con 0-RTT richiede OpenSSL aggiornato) e cosa invece continua a essere un mito da sfatare.
Il conto salato dell’handshake TLS ripetuto
Ogni nuova connessione TLS 1.2 costa un round trip aggiuntivo rispetto a una connessione già “nota” al server; TLS 1.3 lo riduce a un solo round trip nel caso normale, e a zero con il resumption. Il problema è che di default la session cache di Nginx è minuscola e la sua durata troppo breve per traffico reale distribuito su più server.
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
ssl_session_tickets on;
Un dettaglio che quasi nessuno controlla: 1 MB di cache condivisa contiene circa 4.000 sessioni. Con 10m si arrivano a 40.000 sessioni attive, un valore ragionevole per un sito di media grandezza ma da ricalcolare se avete decine di migliaia di client concorrenti (osservate ssl_session_cache statistiche via nginx -V con modulo stub_status compilato, oppure strumentate a livello di access log).
Se gestite un parco di più server dietro un load balancer, i session ticket devono usare la stessa chiave su tutte le istanze, altrimenti ogni volta che il bilanciatore sposta il client su un nodo diverso l’handshake riparte da zero, vanificando il resumption. La chiave va generata una volta e distribuita in modo sicuro (es. tramite un secret manager), non rigenerata ad ogni deploy.
Cifrari: meno scelta, meno lavoro per la CPU
Su TLS 1.3 il set di cifrari è già ristretto e sicuro per design, ma su TLS 1.2 — che va ancora mantenuto attivo per compatibilità con client legacy su siti pubblici — vale la pena essere espliciti ed escludere tutto ciò che non è AEAD (GCM o ChaCha20-Poly1305):
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers off;
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';
Nota sul ssl_prefer_server_ciphers off: con TLS 1.3 e client moderni è il client a scegliere in modo sensato, quindi forzare l’ordine lato server (utile in epoca TLS 1.0/1.1 per evitare cifrari deboli) oggi aggiunge solo complessità. Se avete ancora bisogno di forzare l’ordine per policy di compliance, impostatelo su on e mantenete la lista sopra come riferimento.
Per non reinventare la ruota ogni volta, usate il generatore di configurazione SSL di Mozilla, che tiene aggiornati i profili “modern”, “intermediate” e “old” in base alle CVE e al supporto browser corrente.
Il buffer TLS che nessuno ridimensiona
Una delle ottimizzazioni meno note e più efficaci riguarda ssl_buffer_size. Di default Nginx usa un buffer da 16 KB per i record TLS, pensato per massimizzare il throughput su file di grandi dimensioni. Per pagine HTML, API JSON e asset piccoli — cioè la stragrande maggioranza del traffico applicativo — questo significa che il client deve attendere di ricevere l’intero buffer prima di poter iniziare a renderizzare qualsiasi cosa.
ssl_buffer_size 4k;
Riducendo il buffer a 4 KB il primo record TLS utile arriva prima, con un impatto misurabile sul TTFB percepito (tipicamente nell’ordine di 30-50ms su connessioni con latenza medio-alta). Il compromesso è un overhead leggermente maggiore per trasferimenti di grandi file per via del maggior numero di record; per questo motivo, se servite prevalentemente download di file di grandi dimensioni da un host dedicato, vale la pena valutare un buffer intermedio (es. 8k) o configurazioni separate per server block diversi.
OCSP stapling: una direttiva ormai innocua
Per anni la configurazione “corretta” includeva l’OCSP stapling per evitare che il browser dovesse contattare l’authority per verificare la revoca del certificato:
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /path/to/full_chain.pem;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;
Se usate Let’s Encrypt, sappiate che questa configurazione oggi non fa più nulla: dal 6 agosto 2025 Let’s Encrypt ha terminato il supporto agli endpoint OCSP, spostandosi esclusivamente su Certificate Revocation List (CRL) a corto raggio. Non è un errore lasciare le direttive nella configurazione (sono semplicemente inerti), ma se il vostro certificato proviene da un’altra CA verificate lo stato del suo servizio OCSP prima di considerarle superflue.
HTTP/3 e QUIC: attenzione al firewall, non solo a Nginx
HTTP/3 è disponibile in mainline Nginx dalla versione 1.25.0 e nei pacchetti binari ufficiali di nginx.org; l’adozione globale è ancora intorno al 21% contro il 50%+ di HTTP/2, ma per applicazioni con utenti su reti mobili o ad alta latenza il guadagno di QUIC (0-RTT, niente head-of-line blocking a livello di trasporto) è reale.
listen 443 ssl;
listen 443 quic reuseport;
http2 on;
add_header Alt-Svc 'h3=":443"; ma=86400';
Due avvertenze pratiche, spesso trascurate:
reuseportdeve comparire su una sola direttivalisten, altrimenti Nginx non parte o bilancia male tra i worker.- QUIC viaggia su UDP: se la porta 443/UDP non è aperta sul firewall, il fallimento è silenzioso. Il browser prova QUIC, non riceve risposta e ricade automaticamente su HTTP/2 senza loggare alcun errore visibile lato client. Verificate esplicitamente con
ufw allow 443/udp(o l’equivalente per il vostro firewall) e controllate concurl --http3o la colonna “Protocol” di Chrome DevTools.
Per il 0-RTT (early data) su QUIC serve OpenSSL 3.5.1 o successivo: con versioni precedenti HTTP/3 funziona comunque, semplicemente senza questa ottimizzazione aggiuntiva sul primo round trip.
Header di sicurezza che costano zero millisecondi
Non influenzano il TTFB ma sono ormai lo standard minimo per qualunque endpoint HTTPS in produzione:
add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload";
add_header X-Frame-Options sameorigin;
add_header X-Content-Type-Options nosniff;
Da notare: X-XSS-Protection va rimosso, non aggiunto — i browser moderni lo ignorano e in alcuni casi storici introduceva vulnerabilità XSS reflected invece di prevenirle.
Il limite di questa ottimizzazione: dove il TLS tuning non arriva
Vale la pena essere onesti su un punto: il tuning TLS riduce l’overhead del trasporto sicuro, ma non corregge un’applicazione lenta. Se il vostro TTFB è dominato da query database non indicizzate, da un backend PHP-FPM sottodimensionato o dall’assenza di una cache applicativa, i millisecondi guadagnati qui sono nell’ordine del rumore statistico rispetto ai secondi persi altrove. Il tuning TLS va trattato come l’ultimo 10% dell’ottimizzazione, da applicare dopo aver sistemato caching, query e CDN — non come sostituto.
Procedura di verifica
Dopo ogni modifica, il ciclo è sempre lo stesso:
nginx -t
nginx -s reload
nginx -t valida la sintassi prima del reload, evitando downtime per un errore di battitura in produzione. Per validare l’effetto reale, misurate il TTFB prima e dopo con strumenti come curl -w "%{time_starttransfer}\n" -o /dev/null -s https://vostro-sito.tld ripetuto più volte, oppure con WebPageTest per una view completa lato client reale.
Conclusione
Nessuna di queste modifiche richiede un downtime pianificato o un cambio architetturale: sono direttive di configurazione che si testano e si applicano in pochi minuti. Il ritorno, moltiplicato per milioni di richieste al mese, è tutt’altro che trascurabile — ed è uno di quei rari casi in cui “ottimizzazione infrastrutturale” non significa comprare più hardware, ma semplicemente smettere di lasciare Nginx sui default di cinque anni fa.
Fonte originale: Nginx tuning tips: HTTPS/TLS – Turbocharge TTFB/Latency, LinuxBlog.io. Approfondimenti aggiuntivi su HTTP/3 in produzione: Serving HTTP/2 and HTTP/3 with Nginx in 2026.