Logo David Burdelak
Webdevelopment

Błąd 504 (Gateway Timeout) - co oznacza i jak go naprawić?

Błąd 504 (Gateway Timeout)

Błąd 504 Gateway Timeout oznacza, że serwer pośredniczący, np. Nginx, load balancer albo CDN, przekazał żądanie do aplikacji i nie doczekał się odpowiedzi w ustalonym czasie. Aplikacja zwykle nadal działa, tylko odpowiada za wolno, więc błąd 504 to przede wszystkim problem wydajności, a nie awarii. Najczęściej spotykam go przy eksportach, imporcie produktów, raportach i stronach, które w trakcie ładowania czekają na zewnętrzne API. W tym wpisie pokazuję, jak znajduję operację, która trwa za długo, i jak ją naprawiam, zamiast tylko wydłużać limity czasu.

Dlaczego serwer nie zdążył z odpowiedzią

Każda warstwa między użytkownikiem a aplikacją ma własny limit czasu. Błąd 504 zwraca ta, której limit skończy się pierwszy:

WarstwaUstawienieWartość domyślna
Nginx jako proxy dla Node.js lub innej aplikacjiproxy_read_timeout60 s
Nginx z PHP-FPMfastcgi_read_timeout60 s
PHPmax_execution_time i request_terminate_timeout w PHP-FPMzależnie od konfiguracji hostingu, często 30 s
Cloudflareczas oczekiwania na serwer źródłowy100 s, po przekroczeniu Cloudflare pokazuje błąd 524

Za przekroczeniem limitu stoi niemal zawsze jedna z czterech przyczyn: wolne zapytanie do bazy danych, długa operacja wykonywana w trakcie ładowania strony, np. generowanie PDF albo import, czekanie na zewnętrzne API, które przestało odpowiadać, albo przeciążony serwer, na którym żądania stoją w kolejce do wolnych procesów.

Jak diagnozuję i naprawiam błąd 504

1. Mierzę, ile trwa odpowiedź i która warstwa ją przerywa

curl -o /dev/null -s -w "status: %{http_code}  TTFB: %{time_starttransfer}s  razem: %{time_total}s\n" https://example.pl/raport/

Jeśli błąd pojawia się zawsze po tym samym czasie, np. po 60 sekundach, od razu wiem, który limit zadziałał. Jeśli strona za CDN zwraca błąd, a bezpośrednio z serwera odpowiada po kilkudziesięciu sekundach, problemem jest wolna aplikacja, a CDN tylko pierwszy przestaje czekać.

2. Znajduję wolny kod

W PHP-FPM włączam dziennik wolnych żądań. Po przekroczeniu ustawionego czasu PHP zapisuje w nim ślad wywołań, czyli dokładnie pokazuje, w której funkcji skrypt utknął:

request_slowlog_timeout = 5s
slowlog = /var/log/php-fpm/slow.log

Równolegle włączam w MySQL lub MariaDB dziennik wolnych zapytań. Najczęściej znajduję w nim zapytania bez indeksu albo pobieranie danych w pętli, po jednym zapytaniu na każdy produkt. Typowe problemy z bazą danych w WordPressie i innych systemach opisuje wydajna komunikacja z bazą danych w CMS, a sposób przeszukiwania logów pokazuje analiza logów serwera.

3. Przenoszę długie operacje poza żądanie

Eksport tysięcy zamówień, generowanie raportu czy import produktów nie powinny się wykonywać w czasie, gdy przeglądarka czeka na odpowiedź. Takie zadania przenoszę do kolejki albo zadania uruchamianego w tle, a użytkownikowi pokazuję komunikat, że plik będzie gotowy za chwilę lub zostanie wysłany e-mailem. W WordPressie zamieniam też WP-Cron, uruchamiany przy wejściach odwiedzających, na prawdziwe zadanie systemowe cron.

4. Ustawiam krótkie limity dla zewnętrznych usług

Gdy strona pobiera dane z zewnętrznego API, np. stany magazynowe albo kursy walut, ustawiam w kodzie limit czasu połączenia na kilka sekund i obsługuję jego przekroczenie, np. pokazując dane z pamięci podręcznej. Bez tego jedna niedziałająca usługa zewnętrzna zatrzymuje procesy PHP do granicy limitu i blokuje całą stronę.

5. Wydłużam limity tylko tam, gdzie to uzasadnione

Zwiększenie fastcgi_read_timeout czy max_execution_time usuwa objaw, ale każdy proces czekający dłużej blokuje miejsce dla innych użytkowników. Dlatego wydłużam limity wyłącznie dla konkretnych adresów, np. panelu importu, a nie dla całej strony.

Błąd 504 a szybkość strony i SEO

Błąd 504 to skrajny przypadek wolnego serwera. Zanim odpowiedź przekroczy limit, strona przez dłuższy czas odpowiada wolno, a długi czas oczekiwania na pierwszy bajt pogarsza LCP i całe Core Web Vitals. Googlebot traktuje 504 jak każdy błąd 5xx: przy powtarzających się błędach ogranicza indeksowanie. Różnicę między 504 a błędem 502 zapamiętuję prosto: 502 to zła odpowiedź albo zerwane połączenie, 504 to brak odpowiedzi w wyznaczonym czasie.

Pozostałe błędy HTTP

Każdy kod błędu wskazuje na inną warstwę, więc diagnozę zaczynam od innego miejsca: