f in x
> cd .. / HUB_EDITORIALE > Visualizza in Inglese
Sistemi Operativi & Sicurezza

Nginx Performance Tuning — Cache, Keepalive e Worker Process per Server più Veloci

[2026-06-27] Author: Ing. Calogero Bono
Zenithby Meteora Web Il sistema operativo della tua attività. Social, clienti, prenotazioni e fatture in un'unica piattaforma. Palestre, barber, professionisti. Scopri Zenith Demo gratis · senza carta

Hai un Nginx che funziona, ma senti che il server potrebbe spingere di più. Le pagine caricano in 2 secondi invece di 800ms, il carico CPU sale senza motivo, e le connessioni concorrenti sembrano strozzarsi. Il problema, quasi sempre, non è la macchina: è la configurazione di default. Noi, di Meteora Web, lo vediamo ogni volta che prendiamo in mano un server nuovo: worker process, keepalive e cache sono le tre leve che separano un server pigro da un server che vola. E non serve essere sysadmin da dieci anni per ottimizzarle — serve capire cosa fa ogni direttiva e dove mettere le mani. In questa guida ti portiamo direttamente al sodo: tre aree di intervento, codici pronti da copiare, e la logica per non rompere nulla.

Quanto incidono worker process e worker connections sulle performance?

È la prima domanda che ci fanno i clienti quando guardiamo il loro nginx.conf: «Ma metto worker_processes 8 o 4?». La risposta è più sottile di quanto sembri. Nginx non è Apache: non crea un processo per connessione. Usa un modello event-driven asincrono. Questo significa che un singolo worker può gestire migliaia di connessioni simultanee — se configurato bene.

Il numero di worker corretto

La regola classica: un worker per core CPU. Su server moderni con hyper-threading, il valore auto è la scelta migliore perché Nginx rileva il numero di core disponibili. Non forzarlo mai a un numero superiore ai core fisici: aumenti solo il context switching senza guadagno. Ecco la configurazione base:

Sponsored Protocol

worker_processes auto;
worker_rlimit_nofile 65535;

worker_rlimit_nofile alza il limite di file descriptor per ogni worker — fondamentale se gestisci molte connessioni. Di default il sistema operativo ha limiti bassi (1024). Senza questo, anche con worker allo stato bagnato, il server rifiuta connessioni.

worker_connections: quanto può reggere un worker?

La direttiva worker_connections definisce il massimo numero di connessioni che un singolo worker può aprire contemporaneamente. Il valore totale massimo è worker_processes × worker_connections. Per un server medio (4 core, 8GB RAM) con traffico normale, 4096 è un ottimo punto di partenza:

events {
    worker_connections 4096;
    multi_accept on;
    use epoll;
}
  • multi_accept on: fa accettare più connessioni in un colpo solo dal worker. Su Linux con epoll è d’obbligo per non perdere pacchetti.
  • use epoll: forza Nginx a usare il metodo di multiplexing più efficiente su Linux. Di default lo rileva automaticamente, ma esplicitarlo non fa male.

Errore comune: impostare worker_connections a 65535 e poi non alzare worker_rlimit_nofile. Il sistema blocca il worker prima ancora che Nginx provi a gestire quel numero di connessioni. Controlla sempre i limiti di sistema con ulimit -n e, se serve, modificali in /etc/security/limits.conf.

Sponsored Protocol

Come configurare keepalive per ridurre overhead di connessione?

Ogni connessione TCP costa: handshake, negoziazione TLS (se HTTPS), chiusura. Se il browser apre una connessione per ogni singola risorsa (CSS, JS, immagini), i client si accumulano e il server si intasa. Keepalive riutilizza la stessa connessione per più richieste, riducendo la latenza e il carico. La differenza? Un server senza keepalive può gestire 100 utenti con 1000 richieste; con keepalive ben configurato, gli stessi 100 utenti generano 100 richieste — il resto sono riutilizzi.

Proxy verso backend (PHP, Node, etc.)

La maggior parte del traffico passa da Nginx a un backend (PHP-FPM, Gunicorn, Node). Qui keepalive è doppiamente cruciale: evita di aprire una nuova connessione TCP per ogni richiesta verso il backend. Configurazione base per upstream:

upstream php_backend {
    server 127.0.0.1:9000;
    keepalive 32;
}

server {
    location ~ \.php$ {
        fastcgi_pass php_backend;
        fastcgi_keep_conn on;
        include fastcgi_params;
    }
}

keepalive 32 dice a Nginx di mantenere aperte fino a 32 connessioni verso il backend, da riutilizzare. fastcgi_keep_conn on abilita il keepalive per il backend FastCGI. Senza quest’ultima, le connessioni vengono chiuse dopo ogni richiesta — e le direttive upstream keepalive diventano inutili.

Sponsored Protocol

Keepalive lato client (visitatore)

Per i client finali, Nginx di default tiene la connessione aperta per 75 secondi (keepalive_timeout 75). Questo va bene per siti statici, ma su applicazioni dinamiche con login e AJAX può essere ridotto a 30 secondi per liberare risorse più velocemente. Ecco un bilanciamento tipico:

keepalive_timeout 30;
keepalive_requests 100;

keepalive_requests 100 limita il numero di richieste su una singola connessione keepalive. Dopo 100 richieste, la connessione viene chiusa e una nuova viene creata. Utile per evitare che una connessione rimanga aperta troppo a lungo su un client difettoso.

Quali direttive di caching usare per ridurre carico e velocizzare risposte?

Il caching in Nginx è un silos di performance: se ben configurato, le pagine statiche o le risposte API vengono servite dalla cache senza toccare il backend. Noi, di Meteora Web, abbiamo ridotto il carico CPU del 70% su un e-commerce con traffico stagionale solo abilitando proxy_cache per le pagine prodotto non personalizzate. Il trucco è sapere cosa mettere in cache e per quanto.

Proxy cache per reverse proxy (pagine dinamiche)

Se Nginx agisce da proxy per un’applicazione (WordPress, Laravel, API), puoi memorizzare le risposte in una cache su disco. Configurazione base:

proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=mycache:10m max_size=1g inactive=60m use_temp_path=off;

server {
    location / {
        proxy_cache mycache;
        proxy_cache_key "$scheme$request_method$host$request_uri";
        proxy_cache_valid 200 302 60m;
        proxy_cache_valid 404 1m;
        proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
        proxy_pass http://backend;
    }
}
  • proxy_cache_path: definisce dove salvare la cache. levels=1:2 organizza i file in sottodirectory per evitare troppi file nella stessa cartella. max_size=1g limita la cache a 1GB. inactive=60m rimuove i file non acceduti per 60 minuti.
  • proxy_cache_valid: per quanto tempo tenere in cache le risposte con codice 200/302 (60 minuti) e 404 (1 minuto).
  • proxy_cache_use_stale: se il backend crasha, Nginx serve la versione scaduta della cache — meglio di un errore 502.

FastCGI cache per PHP

Per WordPress, Laravel e altri CMS PHP, fastcgi_cache è ancora più diretto: cache delle pagine renderizzate da PHP-FPM. Configurazione tipica:

Sponsored Protocol

fastcgi_cache_path /var/cache/nginx/fastcgi levels=1:2 keys_zone=phpcache:10m max_size=2g inactive=60m use_temp_path=off;

server {
    location ~ \.php$ {
        fastcgi_cache phpcache;
        fastcgi_cache_key "$scheme$request_method$host$request_uri";
        fastcgi_cache_valid 200 60m;
        fastcgi_pass php_backend;
    }
}

Attenzione: non cachetare pagine con cookie di sessione o contenuti personalizzati. Puoi escluderle con fastcgi_cache_bypass $http_cookie se il cookie contiene un token di autenticazione. Altrimenti rischi di servire a un utente loggato la pagina di un altro.

Sponsored Protocol

Cosa fare adesso

Hai tre leve da tirare subito:

  1. Controlla la configurazione attuale: sul tuo server esegui nginx -t per verificare errori, poi nginx -T | grep -E 'worker_processes|worker_connections|keepalive|proxy_cache' per vedere cosa hai ora.
  2. Applica le modifiche graduali: una direttiva alla volta. Ricarica Nginx con nginx -s reload e testa con ab -n 1000 -c 100 https://tuosito.com/ (Apache Benchmark) o con wrk per misurare richieste al secondo e latenza.
  3. Monitora con amp;gtop o netdata: guarda l’uso CPU, memoria, numero di connessioni attive (nginx -s reopenlog?). Se vedi picchi di worker_connections esaurite (errori 503 nel log), aumenta il valore e controlla ulimit.
  4. Non dimenticare la sicurezza: una cache va ripulita periodicamente e protetta da accessi non autorizzati. Usa proxy_cache_purge se hai bisogno di invalidare cache su richiesta.

Per approfondire tutti i fondamenti di Nginx in produzione, leggi la nostra guida pillar su Nginx e Web Server Configuration. Lì tocchiamo anche virtual host, SSL, log e molto altro — quello che ti serve per non avere più scuse.

Ing. Calogero Bono

> AUTHOR_EXTRACTED

Ing. Calogero Bono

Ingegnere Informatico, co-fondatore di Meteora Web. Esperto in architetture software, sicurezza informatica e sviluppo sistemi scalabili.
[ Read Full Dossier ]

> METEORA_WEB // WEB AGENCY

Costruiamo la presenza digitale che la tua azienda merita.

Siti web, social, pubblicità online, e-commerce e hosting performante: ingegnerizzati con metodo da ingegneri informatici a Sciacca, per tutta Italia.

> MW_JOURNAL

> READ_ALL()