Помилка 504 Gateway Timeout означає, що проміжний сервер (Nginx, Apache, Cloudflare або інший проксі) не дочекався відповіді від сервера, який мав згенерувати сторінку, і припинив очікування. Найчастіше винні повільний PHP-скрипт чи запит до бази даних, переповнений пул PHP-FPM або нестача ресурсів хостингу. Відвідувачу варто оновити сторінку за хвилину-дві, а власнику сайту знайти в error.log рядок upstream timed out і з’ясувати, яка ланка не встигла відповісти.
Що означає 504 і чим вона відрізняється від 502, 503 і 524
Сайт відповідає не одним сервером, а ланцюжком. Браузер звертається до Cloudflare чи іншого CDN (якщо він є), той до Nginx на хостингу, Nginx передає PHP-запит у PHP-FPM (іноді через Apache), а PHP звертається до MySQL і зовнішніх API. Кожна ланка чекає на наступну обмежений час. Коли ліміт вичерпано, проксі повертає 504: бекенд знайдено, але відповіді від нього не дочекалися.
Важливий наслідок: 504 не означає, що дія не виконалася. Nginx перестав чекати, але PHP-скрипт міг працювати далі й завершити імпорт, оплату чи відправлення листа.

| Код | Що сталося | Де шукати причину |
|---|---|---|
| 500 Internal Server Error | Застосунок завершився з помилкою | Лог PHP, .htaccess, код теми чи плагіна |
| 502 Bad Gateway | Бекенд відповів некоректно або обірвав з’єднання | PHP-FPM не запущений, процес примусово завершено, сокет недоступний |
| 503 Service Unavailable | Сервер тимчасово не приймає запити | Перевантаження, ліміти хостингу, режим обслуговування |
| 504 Gateway Timeout | Бекенд не відповів вчасно | Повільний скрипт, база даних, черга PHP-FPM, тайм-аути |
| 522 (Cloudflare) | Cloudflare не зміг встановити TCP-з’єднання з сервером | Сервер недоступний, фаєрвол, неправильний IP у DNS |
| 524 (Cloudflare) | З’єднання є, але відповіді немає 125 секунд | Довгий запит на сервері, як і у випадку 504 |
Якщо бачите інший код, допоможуть окремі розбори: помилка 500 на хостингу і помилка 502 Bad Gateway. Не плутайте 504 з ERR_CONNECTION_TIMED_OUT: тоді сервер не відповів зовсім, а 504 означає відповідь, яку надіслав проксі.
Що робити відвідувачу, якщо сайт показує 504
Проблема майже завжди на боці сайту, але кілька кроків відвідувач може зробити сам:
- Зачекайте 1-2 хвилини й оновіть сторінку (Ctrl+F5 у Windows, Cmd+Shift+R у macOS). Пікове навантаження часто минає саме собою.
- Перевірте, чи сайт недоступний для всіх. Відкрийте його через мобільний інтернет або сервіс перевірки доступності на кшталт Down For Everyone Or Just Me.
- Вимкніть VPN, проксі чи корпоративний шлюз. Вони теж є проміжною ланкою і можуть повертати власну 504.
- Очистіть DNS-кеш, якщо сайт нещодавно переїжджав:
ipconfig /flushdnsу Windows абоsudo dscacheutil -flushcache; sudo killall -HUP mDNSResponderу macOS. - Не повторюйте оплату чи замовлення одразу. Спершу перевірте пошту або особистий кабінет: операція могла пройти, навіть якщо ви побачили 504.
- Повідомте власникові сайту точний час, адресу сторінки і що ви робили: так він швидше знайде запис у логах.
Основні причини 504 на сервері
- Повільний PHP-код. Важкий плагін, генерація звіту, імпорт товарів, бекап з адмінки.
- Повільна база даних. Запит без індексу, роздута таблиця, блокування таблиці іншим процесом.
- Зовнішній API не відповідає. Платіжний шлюз, служба доставки, курси валют, сервер ліцензій плагіна. PHP чекає, а
max_execution_timeцей час не враховує. - Вичерпано пул PHP-FPM. Усі процеси (
pm.max_children) зайняті, нові запити стоять у черзі, доки Nginx не припинить очікування. - Брак ресурсів. CPU на 100%, бракує пам’яті й працює swap, повільний диск, ліміти тарифу.
- Боти й атаки. Масові запити до
xmlrpc.php,wp-login.php, пошуку чи фільтрів каталогу займають усі процеси PHP. - Неузгоджені тайм-аути. Наприклад, Nginx чекає 300 секунд, а Apache за ним лише 30, або Cloudflare обриває запит на 125-й секунді.
- Мережа між проксі й бекендом. Бекенд зупинився, фаєрвол блокує порт, після переїзду в DNS чи Cloudflare лишився старий IP.
Діагностика для власника сайту: команди і логи
Діагностика відповідає на два питання: яка ланка віддала 504 і на якому запиті бекенд не встиг відповісти. Команди виконуються через SSH, а на віртуальному хостингу лог помилок домену зазвичай є в панелі керування.
Крок 1. Заміряйте час до помилки
curl -s -o /dev/null -w "HTTP %{http_code} TTFB %{time_starttransfer}s total %{time_total}s\n" https://example.com/wp-admin/
Секунда, на якій приходить 504, підказує винуватця: близько 30 с вказує на тайм-аут Apache (Timeout 30 у типовій конфігурації деяких панелей хостингу), 60 с на стандартні значення Nginx, 125 с на Cloudflare (тоді код буде 524), 300 с на значення з типового nginx.conf деяких панелей.
Крок 2. Cloudflare чи ваш сервер: хто віддав 504
Перегляньте заголовки: curl -sI https://example.com/. Рядки server: cloudflare і cf-ray означають, що запит пройшов через Cloudflare. Далі орієнтуйтеся на вигляд сторінки:
- Фірмова сторінка Cloudflare зі схемою Browser → Cloudflare → Host, де біля Host стоїть Error: 504 віддав ваш сервер, причину шукайте на хостингу.
- Проста сторінка без оформлення Cloudflare: збій на боці Cloudflare. Якщо він не минає, напишіть у підтримку Cloudflare, додавши час, URL і вивід
example.com/cdn-cgi/trace. - Помилка 524: сервер не відповів за 125 секунд. Підняти цей ліміт (до 6000 с) можна лише на тарифі Enterprise.
Щоб перевірити сервер в обхід Cloudflare, зверніться напряму до IP origin:
curl -s -o /dev/null -w "%{http_code} %{time_total}s\n" --resolve example.com:443:203.0.113.10 https://example.com/
Операції, які справді тривають понад 125 секунд (великий експорт, бекап), Cloudflare радить винести на піддомен у режимі DNS only (сіра хмаринка) або переробити на фонове виконання з перевіркою статусу.
Крок 3. Знайдіть «upstream timed out» в error.log Nginx
sudo grep "upstream timed out" /var/log/nginx/error.log | tail -n 20
sudo tail -f /var/log/nginx/domains/example.com.error.log
Типовий запис виглядає так:
2026/09/11 14:20:01 [error] 1187#1187: *48213 upstream timed out (110: Connection timed out) while reading response header from upstream, client: 198.51.100.25, server: example.com, request: "POST /wp-admin/admin-ajax.php HTTP/2.0", upstream: "fastcgi://unix:/run/php/php8.3-fpm.sock:", host: "example.com"
Тут є час, URL (request), бекенд (upstream) і фаза, на якій сплив ліміт:
while reading response header from upstream: найчастіший варіант, коли бекенд прийняв запит, але не почав відповідати. Скрипт повільний або запит чекав у черзі PHP-FPM. Ліміт задаєfastcgi_read_timeoutчиproxy_read_timeout.while connecting to upstream: не вдалося з’єднатися (бекенд не запущений, порт закритий, помилка в IP). Ліміт задаєproxy_connect_timeout.while sending request to upstream: перевантажений бекенд не приймає тіло запиту.while reading upstream: відповідь почалася, але зупинилася посередині (генерація великого файлу, потокова видача).
Записи upstream prematurely closed connection і connect() ... failed (111: Connection refused) дають уже 502, а не 504. Як системно читати логи хостингу, ми розповідали окремо.
Крок 4. Перевірте PHP-FPM: max_children і slowlog
sudo grep -E "max_children|execution timed out" /var/log/php8.3-fpm.log | tail
# [11-Sep-2026 14:18:02] WARNING: [pool www] server reached pm.max_children setting (5), consider raising it
Повідомлення про pm.max_children означає, що всі процеси зайняті й нові запити чекають у черзі. Щоб побачити, що саме виконується повільно, увімкніть slowlog у файлі пулу, наприклад /etc/php/8.3/fpm/pool.d/www.conf:
request_slowlog_timeout = 10s
slowlog = /var/log/php8.3-fpm-slow.log
Після sudo systemctl reload php8.3-fpm у файлі з’являться стеки викликів для запитів, довших за 10 секунд:
[11-Sep-2026 14:19:10] [pool www] pid 2345
script_filename = /var/www/example.com/index.php
[0x00007f8a1c0154e0] curl_exec() /var/www/example.com/wp-includes/Requests/src/Transport/Curl.php:205
[0x00007f8a1c015210] wp_remote_get() /var/www/example.com/wp-content/plugins/some-plugin/api.php:88
У цьому прикладі PHP чекає на зовнішній HTTP-запит плагіна. Якщо вгорі стека mysqli_query(), шукайте повільний SQL-запит.
Крок 5. Ресурси сервера і база даних
uptime # load average порівняйте з кількістю ядер (nproc)
free -h # чи вистачає пам'яті, чи зайнятий swap
vmstat 1 5 # стовпець wa - очікування диска
sudo dmesg -T | grep -i -E "oom|killed process"
sudo mysql -e "SHOW FULL PROCESSLIST"
Якщо запити в списку процесів MySQL виконуються десятки секунд або мають стан Waiting for table metadata lock, проблема в базі. Тимчасово увімкніть журнал повільних запитів: SET GLOBAL slow_query_log = 1; SET GLOBAL long_query_time = 2;

Тайм-аути: де налаштовуються і як їх узгодити
Збільшуйте тайм-аути лише після того, як знайшли причину, інакше 504 перетвориться на сторінку, що завантажується п’ять хвилин. Типові значення в таблиці стандартні для кожної програми:
| Параметр | Де налаштовується | Типове значення | Наслідок перевищення |
|---|---|---|---|
| Cloudflare Proxy Read Timeout | Cloudflare, лише тариф Enterprise | 125 с | 524 |
| Nginx proxy_read_timeout | nginx.conf: http, server або location | 60 с (у деяких панелях: 300 с) | 504 |
| Nginx proxy_connect_timeout | nginx.conf | 60 с, зазвичай не більше 75 с | 504 |
| Nginx fastcgi_read_timeout | nginx.conf, поруч із fastcgi_pass | 60 с (у деяких панелях: 300 с) | 504 |
| Apache Timeout / ProxyTimeout | apache2.conf або VirtualHost | 60 с (у деяких панелях: 30 с) | 504 |
| PHP-FPM request_terminate_timeout | файл пулу в pool.d | 0 (вимкнено) | процес завершено, Nginx віддає 502 |
| PHP max_execution_time | php.ini, .user.ini, ini_set() | 30 с (у CLI 0) | Fatal error, сторінка 500 |
| MySQL max_execution_time, MariaDB max_statement_time | my.cnf | 0 (без ліміту) | запит перервано, помилка в PHP |
| WordPress HTTP API | фільтр http_request_timeout | 5 с | помилка запиту в плагіні, не 504 |
Правило узгодження: зовнішні ланки чекають довше за внутрішні, а жорсткий ліміт PHP-FPM трохи більший за ліміт Nginx. Робочий приклад для сайту за Cloudflare: max_execution_time 60 с, fastcgi_read_timeout 90 с, request_terminate_timeout 95 с, Cloudflare 125 с. Без request_terminate_timeout завислий скрипт займає процес і після 504, а кілька таких процесів вичерпують пул.
Nginx + PHP-FPM
# /etc/nginx/sites-available/example.com
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.3-fpm.sock;
fastcgi_read_timeout 90s;
}
; /etc/php/8.3/fpm/pool.d/www.conf
request_terminate_timeout = 95s
php_value[max_execution_time] = 60
sudo nginx -t && sudo systemctl reload nginx
sudo php-fpm8.3 -t && sudo systemctl reload php8.3-fpm
Якщо окремому завданню (імпорт, експорт, перерахунок) потрібно кілька хвилин, не піднімайте ліміти для всього сайту. Запустіть його через WP-CLI або cron: у CLI max_execution_time за замовчуванням 0, а Nginx у такому ланцюжку не бере участі.
Nginx як проксі та Apache
location / {
proxy_pass http://127.0.0.1:8080;
proxy_connect_timeout 10s;
proxy_read_timeout 90s;
}
# /etc/apache2/apache2.conf або всередині VirtualHost
Timeout 90
ProxyTimeout 90
sudo apachectl configtest && sudo systemctl reload apache2
У зв’язці Nginx + Apache в деяких панелях хостингу типовий Apache Timeout дорівнює 30 с, тоді як Nginx чекає 300 с. Тому 504 рівно через 30 секунд, яку не виправляє збільшення max_execution_time, найчастіше спричиняє саме Apache.
PHP: max_execution_time і .user.ini
За документацією PHP, max_execution_time рахує лише час роботи самого скрипту: очікування бази даних, системних викликів і мережевих потоків у Linux до нього не входить. Скрипт, який дві хвилини чекає на API, не отримає Fatal error, а відвідувач побачить 504 від Nginx. На хостингу з PHP-FPM ліміт зазвичай можна змінити файлом .user.ini у корені сайту (рядок max_execution_time = 60), зміни застосовуються протягом 5 хвилин.
504 у WordPress: типові винуватці і рішення
- Плагін. Якщо 504 з’явилася після оновлення, вимкніть плагіни командою
wp plugin deactivate --allабо перейменуйте папкуwp-content/pluginsу файловому менеджері, а потім вмикайте їх по одному. - wp-cron. Завдання за розкладом запускаються під час відвідувань і займають процеси PHP. Вимкніть вбудований запуск і перенесіть його в системний cron (приклад нижче). Детальніше у статті про cron на хостингу.
- admin-ajax.php і Heartbeat. Якщо більшість записів в error.log стосується
admin-ajax.php, винні відкриті вкладки адмінки, конструктор сторінок або плагін статистики, тож зменште частоту Heartbeat. - Роздуті autoload-опції. Починаючи з WordPress 6.6, Site Health попереджає, коли автозавантажувані опції перевищують 800 КБ. Їхній розмір показує
wp option list --autoload=on --format=total_bytes. - Повільні запити. Плагін Query Monitor показує SQL-запити й зовнішні HTTP-виклики з часом виконання.
- Імпорт, експорт, бекапи. Зменште розмір партії в налаштуваннях імпорту, важкі завдання запускайте через WP-CLI. У WooCommerce стежте за чергою Scheduled Actions.
- Боти. Закрийте
xmlrpc.php, якщо він не потрібен, і обмежте спроби входу наwp-login.php. - Відсутній кеш. Кеш сторінок звільняє PHP від більшості запитів, а Object Cache на WordPress-хостингу зменшує кількість звернень до бази.
# wp-config.php
define( 'DISABLE_WP_CRON', true );
# crontab -e (шлях для прикладу): завдання кожні 5 хвилин
*/5 * * * * cd /home/user/web/example.com/public_html && wp cron event run --due-now >/dev/null 2>&1
Віртуальний хостинг чи VPS: що можна змінити самостійно
На віртуальному (shared) хостингу
Конфігурація Nginx, Apache і PHP-FPM спільна для багатьох клієнтів, тому fastcgi_read_timeout ви не зміните. Що доступно:
- переглянути лог помилок домену в панелі керування;
- змінити
max_execution_timeчерез.user.iniабо налаштування PHP у панелі, якщо хостинг їх надає; - оптимізувати сайт: кеш, свіжа версія PHP, менше плагінів, важкі завдання через cron;
- написати в підтримку, вказавши точний час, URL і текст помилки.
Якщо 504 регулярно збігається з піками відвідуваності, сайт, імовірно, упирається в процесорні ліміти на хостингу. Тоді допоможе старший тариф або VPS.
На VPS або виділеному сервері
Тут ви контролюєте весь ланцюжок. Почніть із розрахунку pm.max_children за пам’яттю, середній розмір процесу PHP-FPM покаже команда:
ps --no-headers -o rss -C php-fpm8.3 | awk '{s+=$1} END {printf "%.0f MB\n", s/NR/1024}'
Поділіть пам’ять, яку готові віддати PHP, на цей розмір: 2 ГБ при процесі 80 МБ дають близько 25 процесів. Більше ставити не варто, бо замість 504 отримаєте swap і OOM Killer.
На власному сервері з панеллю керування врахуйте ще три речі. У типовому шаблоні деяких панелей кожен домен має окремий пул із pm = ondemand і pm.max_children = 8, тож дев’ятий одночасний повільний запит уже чекає в черзі. Якщо панель генерує пули з шаблонів, зміни вносьте у власну копію шаблону, інакше панель перезапише їх під час перебудови домену. Додаткові директиви Nginx для одного домену додавайте в окремі файли, які панель підключає до конфігурації домену, а не в згенерований конфіг. Плануєте переїзд сайту з shared-хостингу на VPS? Скористайтеся покроковим посібником про переїзд на інший хостинг без простою.
Часті питання
Чи шкодить помилка 504 SEO?
Короткочасна ні: Google сприймає коди 5xx як тимчасову проблему і сповільнює сканування. Якщо ж помилка триває днями, сторінки можуть поступово випадати з індексу.
Чому збільшення max_execution_time не допомогло?
Бо 504 віддає не PHP, а проксі: Nginx, Apache чи Cloudflare обривають запит раніше, ніж спрацює ліміт PHP. Визначте ланку за часом до помилки.
Чому 504 з’являється лише в адмінці WordPress?
Відвідувачам сторінки часто віддає кеш, а адмінка завжди виконує PHP. До того ж саме там працюють оновлення, імпорт, конструктори сторінок і admin-ajax.php.
Чим 504 відрізняється від 524 у Cloudflare?
Причина однакова: сервер не встиг відповісти. Різниця в тому, хто перестав чекати. Код 524 означає, що 125 секунд чекав Cloudflare, а 504 у фірмовому оформленні Cloudflare означає що тайм-аут спрацював на вашому сервері.
Чи може причиною бути DNS?
Так, якщо після переїзду проксі, балансувальник або Cloudflare досі звертаються на старий IP. Nginx у такому разі пише while connecting to upstream, а Cloudflare частіше показує 522.
Висновок
504 Gateway Timeout є симптомом, а не діагнозом: одна ланка не дочекалася іншої. Заміряйте час до помилки, знайдіть запис «upstream timed out», перевірте пул PHP-FPM і базу, усуньте повільне місце і лише потім узгодьте тайм-аути. Якщо сайту стабільно бракує ресурсів, порівняйте тарифи віртуального хостингу RichHost з NVMe-дисками та власною панеллю керування з ШІ-помічником або оберіть хостинг для WordPress.



