504 Gateway Timeout: backend lenti, timeout e 502 vs 503 vs 504
Un 504 Gateway Timeout significa che un proxy ha raggiunto il tuo backend, ha atteso una risposta, e ha rinunciato prima che ne arrivasse una. Niente è crashato e niente ha rifiutato la richiesta: qualcosa dietro il proxy è più lento di quanto il proxy sia disposto ad aspettare.
Cosa riporta un 504
RFC 9110 definisce il 504 per un server che agisce come gateway o proxy e non ha ricevuto una risposta tempestiva da un server upstream a cui doveva accedere. La parola "tempestiva" è definita dalla configurazione, non dalla specifica, quindi un 504 è sempre un'affermazione su due cose contemporaneamente: quanto era lento il backend, e a quale limite era impostato il proxy.
Questo ha una conseguenza pratica importante. Quando un proxy restituisce 504, il backend di solito continua a lavorare sulla richiesta. La connessione al client è persa, ma la query lenta sta ancora girando, il report è ancora in generazione, e le risorse sono ancora occupate. Ecco perché un'ondata di 504 spesso peggiora un server: ogni richiesta abbandonata lascia lavoro dietro di sé, e la coda cresce più velocemente di quanto si svuoti.
504 contro 502 contro 503
| 502 Bad Gateway | 503 Service Unavailable | 504 Gateway Timeout | |
|---|---|---|---|
| Cosa è successo | Il backend ha dato una risposta non valida o ha chiuso la connessione | Il server ha rifiutato il lavoro di proposito | Il backend ha accettato il lavoro e non ha mai risposto in tempo |
| Stato del backend | Giù, in crash, o parla il protocollo sbagliato | Su, ma sovraccarico o in manutenzione | Su e occupato, ancora in elaborazione |
| Velocità di risposta | Di solito immediata | Di solito immediata | Lenta, arriva al limite del timeout |
| Riga di log tipica | connect() failed oppure upstream prematurely closed connection | Regola di manutenzione, oppure nessun upstream sano | upstream timed out (110: Connection timed out) |
Retry-After | Non usuale | Comune e consigliato | Non usuale |
| Primo posto dove guardare | Il processo backend è in esecuzione? | Capacità, flag di manutenzione, health check | Query lente e dipendenze lente |
In pratica un 502 fallisce rapidamente, un 503 rifiuta educatamente, e un 504 ti fa aspettare prima. La guida dedicata al 502 e la panoramica 5xx coprono gli altri due per intero.
Perché il backend è troppo lento
- Query al database lente. Un indice mancante, una query cresciuta insieme ai dati, un pattern N+1 in un loop, o contesa di lock sotto concorrenza. La causa singola più comune.
- Chiamate lente a terzi. Una richiesta API in uscita senza un proprio timeout eredita la giornata peggiore del servizio remoto e la passa ai tuoi visitatori.
- Cold start. La prima richiesta dopo uno scale-up, un avvio di container o un periodo di inattività paga tutta insieme l'inizializzazione, la creazione delle connessioni e il riscaldamento della cache.
- Lavoro genuinamente pesante su una richiesta web. Generazione di report, esportazioni, elaborazione immagini o importazioni massive gestite in modo sincrono alla fine supereranno qualsiasi timeout ragionevole.
- Contesa di risorse. Saturazione della CPU, pressione sulla memoria e swap rallentano ogni richiesta, quindi le più lente superano per prime il limite.
- Timeout impostati troppo stretti. Se un endpoint ha legittimamente bisogno di più tempo di quanto il proxy consenta, il bug è la configurazione, non il codice.
- Problemi di rete tra i salti. Perdita di pacchetti o ritardi nella risoluzione DNS per l'indirizzo upstream aggiungono latenza che non compare nei tempi dell'applicazione.
Come diagnosticare e correggere un 504
- Misura il tempo fino all'errore. Il ritardo prima di un 504 di solito corrisponde al timeout configurato, il che ti dice quale salto lo ha prodotto:
Un 504 a quasi esattamente 60 secondi indica un timeout di lettura predefinito del proxy. Uno a 30 o 100 secondi indica qualunque componente sia configurato con quel numero, spesso una CDN piuttosto che il tuo proxy.curl -sS -o /dev/null -w "%{http_code} %{time_total}s\n" https://example.com/slow-page - Scopri se è un solo endpoint o tutti. Un singolo URL lento è un problema applicativo. Tutto lento in una volta è saturazione delle risorse o una dipendenza che fallisce.
- Leggi il log degli errori del proxy. Con nginx la riga è esplicita:
Indica l'upstream e la fase, il che distingue una connessione lenta da una risposta lenta.[error] upstream timed out (110: Connection timed out) while reading response header from upstream, upstream: "http://127.0.0.1:8080/" - Cronometra il backend direttamente, senza il proxy. Se la stessa richiesta impiega 90 secondi contro l'origine, il proxy sta riportando la verità e la correzione appartiene all'applicazione.
- Profila il percorso lento. Controlla il log delle query lente, poi le trace dell'applicazione. La maggior parte dei 504 si risolve in una singola query o una singola chiamata in uscita.
- Correggi la causa prima del timeout. Aggiungi l'indice, metti in cache il risultato costoso, oppure sposta il lavoro genuinamente lungo verso un job in background che risponde immediatamente e riporta il progresso separatamente.
- Alza il timeout solo quando il lavoro è legittimamente lungo, e alzalo in modo coerente su ogni salto. Un limite CDN di 30 secondi rende inutile un timeout di origine di 120 secondi.
- Imposta timeout sulle tue chiamate in uscita così una dipendenza lenta fallisce rapidamente con un errore chiaro invece di consumare un worker finché il proxy non rinuncia.
Il tempo di risposta è l'avviso precoce
Un 504 è lo stato finale di un rallentamento che si stava accumulando da un po'. I tempi di risposta vanno alla deriva da mezzo secondo a due secondi a dieci, e nessuno se ne accorge finché le richieste non iniziano a superare il limite. Un controllo HTTP pianificato registra il tempo di risposta di ogni controllo insieme al codice di stato, così la tendenza è visibile come un grafico molto prima del primo timeout, e l'avviso arriva al primo vero fallimento invece che dopo che la coda del supporto si è riempita. Controllare da più regioni aiuta altrettanto, perché una rotta che è veloce da un continente e lenta da un altro indica il percorso di rete o la configurazione edge invece del tuo database.