Ottimizzare il livello applicativo, il database e la cache è il modo più efficace per abbassare il Time To First Byte (TTFB) di un sito servito via HTTPS. Ma c’è un secondo livello, spesso trascurato, dove si possono recuperare decine di millisecondi su ogni singola richiesta a costo zero: la configurazione TLS di Nginx. Handshake lenti, sessioni non riutilizzate e direttive obsolete aggiungono overhead a ogni connessione, soprattutto per i client che non riescono a sfruttare il riutilizzo di sessione. Vediamo come intervenire in modo concreto, direttiva per direttiva.
HTTP/2 e HTTP/3: le basi sono cambiate
Se la vostra configurazione Nginx usa ancora listen 443 ssl http2;, è il momento di aggiornarla: dalla versione 1.25.1 la sintassi combinata è deprecata a favore di una direttiva separata:
listen 443 ssl;
http2 on;
Dalla 1.25.0, inoltre, il supporto nativo a QUIC/HTTP3 è incluso nel ramo mainline, senza bisogno di patch al sorgente o build custom. Per abilitarlo:
listen 443 quic reuseport;
listen [::]:443 quic reuseport;
add_header Alt-Svc 'h3=":443"; ma=86400';
Un paio di dettagli che fanno la differenza: la direttiva reuseport va dichiarata una sola volta per IP e porta (sugli altri server block si usa semplicemente listen 443 quic;), e senza l’header Alt-Svc i browser non hanno modo di scoprire che il server supporta HTTP/3, quindi continueranno a usare HTTP/2. Per verificare che tutto funzioni:
curl --http2 -I https://dominio.it/
curl --http3 -I https://dominio.it/
Session cache e session ticket: evitare l’handshake completo
Ogni handshake TLS completo costa round trip e calcolo crittografico. Riutilizzare una sessione già stabilita li elimina quasi del tutto. La cache condivisa va dimensionata in base al traffico: circa 4.000 sessioni per ogni MB allocato.
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
ssl_session_tickets on;
Un chiarimento importante per chi segue guide datate: per anni la raccomandazione standard è stata disabilitare i session ticket (ssl_session_tickets off;) per motivi di forward secrecy, perché la gestione delle chiavi di cifratura dei ticket era debole. Da Nginx 1.23.2 in poi la gestione è stata irrobustita in modo sostanziale, e oggi la raccomandazione è lasciarli attivi — a meno che non si gestisca un cluster di server dietro load balancer che non condividono e ruotano le chiavi dei ticket tra loro, nel qual caso vanno disattivati o la rotazione va implementata esplicitamente.
Versioni del protocollo: fuori TLS 1.0 e 1.1
TLS 1.0 e 1.1 sono obsoleti, vulnerabili a classi di attacchi note e esplicitamente vietati dallo standard PCI DSS per chi gestisce pagamenti. Per un sito pubblico generico:
ssl_protocols TLSv1.2 TLSv1.3;
Se invece controllate anche i client che si connettono (API interne, microservizi, mobile app proprietarie), potete spingervi oltre:
ssl_protocols TLSv1.3;
TLS 1.3, disponibile da Nginx 1.13, completa l’handshake in un solo round trip (contro i due di TLS 1.2) e supporta nativamente la ripresa di sessione: è probabilmente la singola modifica con il miglior rapporto tra impatto sulla latenza e sforzo di configurazione.
OCSP stapling: una direttiva da rivedere, non da copiare e incollare
La configurazione “classica” per l’OCSP stapling è questa:
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;
Ma se i vostri certificati sono emessi da Let’s Encrypt, queste direttive oggi non fanno più nulla: Let’s Encrypt ha spento i propri responder OCSP il 6 agosto 2025, e i certificati emessi successivamente non contengono più un URL OCSP. Nginx, di conseguenza, si limita a loggare "ssl_stapling" ignored, no OCSP responder URL a ogni reload. Se usate solo certificati Let’s Encrypt potete rimuovere queste righe senza perdere nulla; se la vostra CA pubblica ancora un URL OCSP, mantenerle resta un piccolo beneficio per i client che verificano la revoca in questo modo.
Buffer size: un dettaglio che si sente
Il buffer di invio TLS di Nginx è impostato di default a 16k. Ridurlo a 4k può diminuire il TTFB percepito, perché i dati iniziano a essere trasmessi prima invece di attendere il riempimento del buffer:
ssl_buffer_size 4k;
Il guadagno tipico misurato è nell’ordine di 30-50 ms, ma varia sensibilmente in base al profilo del traffico e alla dimensione media delle risposte: su payload molto grandi un buffer più piccolo introduce più overhead per via del maggior numero di record TLS, quindi vale la pena misurare prima e dopo sul proprio traffico reale.
Cipher suite e configurazione completa
Un esempio di configurazione aggiornata che mette insieme i punti precedenti:
http2 on;
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';
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
ssl_session_tickets on;
ssl_buffer_size 4k;
Due note su questo blocco: ssl_ciphers influisce solo su TLS 1.2, perché le suite di TLS 1.3 sono fissate dallo standard e non configurabili; e ssl_prefer_server_ciphers off è corretto nel 2026, perché sono ormai i client moderni a scegliere le suite più sicure, non il server. Per generare una configurazione aggiornata in base al proprio parco client supportato (moderno, intermedio, compatibilità estesa), conviene affidarsi al Mozilla SSL Configuration Generator invece di mantenere a mano liste di cipher. Prima di ricaricare in produzione, testate sempre la sintassi:
nginx -t
nginx -s reload
Header di sicurezza correlati
Due direttive da affiancare alla configurazione TLS, perché riguardano la stessa superficie di sicurezza:
add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload";
add_header X-Frame-Options sameorigin;
add_header X-Content-Type-Options nosniff;
Da evitare invece l’header X-XSS-Protection, ormai ignorato da tutti i browser moderni che ne hanno rimosso il motore di auditing XSS: la protezione va implementata con una Content-Security-Policy ben definita, non con quell’header legacy.
Quanto incide davvero sul TTFB
Va detto con chiarezza: il tuning TLS riduce l’overhead dell’handshake e migliora il riutilizzo delle connessioni, ma non risolve un’applicazione lenta. Se il TTFB è dominato da query al database non ottimizzate, cache assente o backend sovraccarico, questi interventi si misurano in decine di millisecondi, mentre i problemi applicativi si misurano in centinaia o migliaia. Il tuning TLS va quindi visto come un passaggio di hardening e ottimizzazione a basso sforzo da fare una volta per tutte, non come sostituto dell’ottimizzazione di caching, query e configurazione del backend.
Conclusione
Aggiornare la direttiva HTTP/2, valutare HTTP/3, lasciare attivi i session ticket moderni, eliminare TLS 1.0/1.1, rimuovere lo stapling OCSP inutile su certificati Let’s Encrypt e ridurre il buffer size sono interventi che si implementano in pochi minuti e si verificano subito con nginx -t e un test con curl. Non sostituiscono il lavoro di ottimizzazione lato applicazione, ma su un sito già ben ottimizzato a monte sono spesso il margine che separa un TTFB discreto da uno davvero competitivo.
Fonte: LinuxBlog.io – Nginx tuning tips: HTTPS/TLS – Turbocharge TTFB/Latency.