Nelle infrastrutture web ad alto traffico, un TTFB (Time to First Byte) elevato è quasi sempre imputabile a una cattiva configurazione della comunicazione tra il Web Server (NGINX) e il gestore dei processi PHP (PHP-FPM). Tunare questi due elementi permette di abbattere la latenza di elaborazione ed eliminare gli errori 502 Bad Gateway sotto carico.
1. Comunicazione via Socket UNIX vs TCP Loopback
Di default, molte distribuzioni configurano NGINX per dialogare con PHP-FPM tramite loopback TCP locale su 127.0.0.1:9000. Questo introduce l’overhead dello stack di rete (gestione porte effimere, controlli di pacchetto e stati TIME_WAIT). Il passaggio a socket UNIX locale azzera questo overhead sfruttando la memoria condivisa del kernel Linux.
# /etc/php/8.3/fpm/pool.d/www.conf
listen = /run/php/php8.3-fpm.sock
listen.owner = www-data
listen.group = www-data
listen.mode = 0660
2. Dimensionamento Analitico di pm.max_children
L’errore più comune nei server non ottimizzati è lasciare la gestione dinamica con valori predefiniti oppure sovrastimare pm.max_children, portando la macchina in swap I/O. Il calcolo deve essere rigidamente deterministico basandosi sulla RAM effettivamente riservata a PHP:
# Misura del consumo medio di memoria per processo PHP attivo (MiB)
ps -y -C php-fpm8.3 --sort:-rss | awk '{sum+=$2; count++} END {print "Media MiB: " sum/count/1024}'
# Formula: pm.max_children = (RAM Libera Dedicata a PHP) / (Consumo Medio per Processo)
In un nodo con 4 GB di RAM, riservando 2.5 GB a PHP-FPM con processi medi da 60 MB, il valore corretto è: 2560 / 60 = 42. Impostare la modalità pm = static azzera i costi di fork continuo dei processi sotto traffico costante.
3. Ottimizzazione del FastCGI Buffering in NGINX
Se la risposta generata da PHP supera la dimensione del buffer configurato in NGINX, il web server è costretto a scrivere blocchi temporanei su disco (in /var/lib/nginx/fastcgi), moltiplicando i tempi di I/O. Calibrare i buffer in RAM garantisce una consegna istantanea:
fastcgi_buffers 16 16k;
fastcgi_buffer_size 32k;
fastcgi_busy_buffers_size 64k;
fastcgi_temp_file_write_size 64k;
fastcgi_read_timeout 60s;
4. Verifica e Benchmark del TTFB da Shell
Il profiling del TTFB non va eseguito dal browser (influenzato da estensioni, cache locale e rendering), ma tramite chiamata raw con curl misurando time_starttransfer:
curl -s -o /dev/null -w "DNS: %{time_namelookup}s | Connect: %{time_connect}s | TTFB: %{time_starttransfer}s | Total: %{time_total}s\n" http://127.0.0.1/
Un’architettura configurata con socket UNIX e buffer calibrati garantisce un TTFB stabile inferiore a 60-80 ms per richieste dinamiche WordPress, azzerando le code di elaborazione.
💡 Fuori dal terminale: cosa significa in parole povere?
- Cos’è il TTFB (Time To First Byte): È il tempo di reazione del server. Quando un visitatore clicca su una pagina, il TTFB è il ritardo che intercorre prima che il browser riceva il primissimo byte di dati. Se questo valore supera i 500-800 millisecondi, il sito appare “congelato” e l’utente tende ad abbandonare.
- Il problema delle configurazioni standard: Di default, NGINX e PHP comunicano come due persone che parlano al telefono attraverso una rete interna simulata, aprendo e chiudendo connessioni a ogni visita. Inoltre, PHP crea e distrugge i propri processi continuamente, sprecando tempo prezioso prima di generare la pagina.
- La nostra soluzione: Abbiamo azzerato i passaggi intermedi. NGINX dialoga con PHP direttamente nella memoria del server tramite socket UNIX, i processi PHP rimangono sempre attivi e pronti all’uso (gestione statica), e il codice compilato resta fisso nella memoria RAM (OPcache). Il risultato è una risposta immediata e un caricamento fluido.