504 Gateway Timeout: vinden wat de site vertraagt
· 6 min leestijd
Wat de fout betekent
Bij een 504 geeft de webserver vooraan (nginx, Apache, een load balancer, een CDN) het op met de applicatie erachter: het verzoek is doorgegeven en de backend was nog bezig toen de teller vooraan op nul stond. Het verschil met een 502 Bad Gateway: de backend is bereikbaar, hij is alleen te traag. Gebruikelijke time-outs: 60 seconden in nginx (fastcgi_read_timeout, proxy_read_timeout) en in Apache (ProxyTimeout), 100 seconden bij Cloudflare, en die laatste kun je in het gratis plan niet aanpassen.
De time-out verhogen is zelden de oplossing. Iets duurt te lang, en dat iets moet je vinden.
Veelvoorkomende oorzaken
- Een trage SQL-query. Een plugin die bij elke pagina de rijen van een enorme tabel telt, een ontbrekende index, een tabel
wp_optionsvol verlopen transients. Onder belasting tellen de wachttijden op. - Een externe aanroep die blijft hangen. De applicatie vraagt iets aan een betaalprovider, een maildienst, een weer-API of een licentieserver, en die dienst is traag of down. Zonder eigen time-out wacht jouw pagina mee.
- Te weinig workers. Alle workers van PHP-FPM zitten vast in trage verzoeken; nieuwe komen in de wachtrij tot de server vooraan het opgeeft. Van buitenaf ziet dat eruit als een time-out, ook al zou elk verzoek op zich snel zijn.
- Cron of back-up op de voorgrond. Een back-up, een import, een enorme sitemap: gemaakt binnen een webverzoek overschrijden ze elke time-out.
- Swap. De server komt geheugen tekort, gebruikt swap en alles wordt tien keer trager: hoge belasting, processor nauwelijks bezig.
- Netwerk tussen de server vooraan en de backend. Een load balancer in het ene datacenter, de backend in het andere, een firewall die stilletjes pakketten laat vallen. Zeldzaam, maar een 504 bij elk verzoek met een backend die niets doet, wijst die kant op.
Als je bezoeker bent
Herlaad over een minuut. Is de site traag in plaats van down, probeer dan een andere pagina; misschien is één zware pagina de schuldige.
Als het je eigen site is: eerst controleren
Open de Website down checker: die toont de HTTP-code en de responstijd van buitenaf. Een site die vandaag 30 seconden nodig heeft, geeft morgen een 504.
Op je eigen server zoek je de verloren tijd hier:
# staan er time-outs in de logs?
sudo tail -n 30 /var/log/nginx/error.log | grep -E 'timed out|timeout'
# wat doet PHP? (vereist pm.status_path in de pool)
curl -s 'http://127.0.0.1/fpm-status?full' | grep -E 'state|request URI|duration' | head -40
# MySQL/MariaDB: welke query’s lopen er en hoe lang al?
sudo mysql -e 'SHOW FULL PROCESSLIST;'
# geheugen en swap
free -m
vmstat 1 5
Een lijst vol met dezelfde query of kolommen si/so die niet op nul staan, noemen de oorzaak bij naam.
Oplossingen op je eigen server
1. Het slow-query-log aanzetten en de query repareren
SET GLOBAL slow_query_log = 1;
SET GLOBAL long_query_time = 2;
SET GLOBAL slow_query_log_file = '/var/log/mysql/slow.log';
Na een paar minuten geeft sudo mysqldumpslow -s t /var/log/mysql/slow.log | head de ergste query’s. Maak de ontbrekende index aan of vervang de plugin die de query afvuurt. Op WordPress is de optietabel die maar blijft groeien een klassieker:
wp transient delete --all
wp db query "SELECT option_name, LENGTH(option_value) AS size FROM wp_options WHERE autoload='yes' ORDER BY size DESC LIMIT 20;"
Alles van honderden kilobytes dat bij elk verzoek automatisch wordt geladen, is een kandidaat om te verwijderen.
2. Externe aanroepen een time-out geven
Elke HTTP-aanroep van je applicatie heeft een eigen time-out nodig, korter dan die van de webserver. In PHP met cURL: CURLOPT_CONNECTTIMEOUT op 5 en CURLOPT_TIMEOUT op 10. Op WordPress accepteert wp_remote_get() een argument timeout; veel plugins laten de standaardwaarde staan en wachten eindeloos. Is een externe dienst down, dan moet de pagina in een beperkte versie verschijnen (het formulier zonder de actuele verzendkosten), niet doodgaan.
3. Lange processen uit het verzoek halen
Back-ups, imports, exports, sitemaps en het versturen van e-mails horen in een cronjob of een wachtrij, niet in een pagina. Op WordPress zet je de pseudo-cron uit en installeer je de echte:
// wp-config.php
define('DISABLE_WP_CRON', true);
# crontab -e
*/5 * * * * cd /var/www/example.com && wp cron event run --due-now >/dev/null 2>&1
4. Time-outs met mate aanpassen
Heeft een pagina echt meer tijd nodig (een export, een rapport), verhoog de time-out dan alleen voor die pagina, niet globaal:
location = /wp-admin/export.php {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.3-fpm.sock;
fastcgi_read_timeout 300;
}
Apache: ProxyTimeout 300 binnen een <Location>-blok. Zet max_execution_time van PHP op dezelfde waarde; anders geeft PHP het als eerste op met een 500. Daarna sudo nginx -t && sudo systemctl reload nginx.
5. Stoppen met swappen
ps aux --sort=-%mem | head
Neemt elke PHP-FPM-worker 150 MB in en start je er 30 op een server met 4 GB, dan klopt de rekensom niet. Verlaag pm.max_children, voeg geheugen toe of repareer de plugin die het opslokt. Een server die niet swapt, is een server waarvan de meeste 504’s verdwijnen.
6. Een cache plaatsen
Een paginacache (de FastCGI-cache van nginx, een WordPress-plugin, Varnish) bedient bezoekers zonder PHP of de database aan te raken. De meeste 504’s onder belasting verdwijnen zodra de meestbezochte pagina’s daaruit komen.
Ligt het bij je hostingprovider?
Op shared hosting kun je trage query’s en plugins repareren, maar niet de time-outs van de server of de belasting door je buren:
Goedemiddag, mijn website example.com geeft sinds ongeveer 16:00 (UTC) “504 Gateway Timeout”. Pagina’s die tot nu toe snel waren, lopen nu tegen de time-out aan. Ik heb niets gewijzigd. Kunt u controleren of de databaseserver of de PHP-pool van mijn account overbelast is, of dat een ander account veel belasting veroorzaakt?
Zo gebeurt het niet opnieuw
Een 504 is een trage site die nog trager is geworden, en de responstijd is lang vóór de time-out te meten. De websitecontroles leggen hem bij elke ronde vast; zet er een melding op en je ziet de trend ruim voordat bezoekers een fout zien. Server monitoring voegt belasting, geheugen en swap van binnenuit toe.
Down? Wij fixen het. Op je eigen server of op shared hosting met SSH-toegang vindt de Deep Fix, de grondige reparatie, de trage query of de hangende aanroep en repareert hij die, 24 uur per dag, ook in het weekend, per blok van 15 minuten, met de prijs in beeld voordat je bestelt; de schatting is de bovengrens. De Quick Fix herstart tegen een vaste prijs een gestopte dienst.
En nu
Controleer het van buitenaf
Is de site voor iedereen down of alleen bij jou, en wat antwoordt de server? Gratis, zonder account.
Website down checkerDown? Wij fixen het.
Op je eigen server of op shared hosting met SSH-toegang: Quick Fix tegen een vaste prijs voor de meest voorkomende oorzaken, Deep Fix gefactureerd per blok van 15 minuten voor al het andere, 24/7. Prijs zichtbaar vóór je bestelt.
Reparatie bestellenMeer uit de kennisbank
- Website down: wat je doet in de eerste 15 minuten
- Server down of niet bereikbaar: wat je controleert en in welke volgorde
- 500 Internal Server Error: de oorzaak vinden in de logs en de site weer online krijgen
- 502 Bad Gateway: de oorzaak vinden en oplossen
- 503 Service Unavailable: overbelasting, onderhoud of een limiet van de hosting?
- Cloudflare-fout 521 en 522: de origin-server antwoordt niet
- DNS_PROBE_FINISHED_NXDOMAIN: het domein antwoordt niet meer
- ERR_CONNECTION_REFUSED: de server weigert de verbinding
- ERR_CONNECTION_TIMED_OUT: de server antwoordt niet op tijd
- Wat “Je verbinding is niet privé” betekent en hoe je het oplost
- ERR_SSL_PROTOCOL_ERROR: de veilige verbinding mislukt nog vóór het certificaat
- ERR_TOO_MANY_REDIRECTS: de doorverwijzingslus vinden en doorbreken
- 403 Forbidden: wat de toegang tot je site blokkeert
- ERR_CONNECTION_RESET: waarom de verbinding halverwege wegvalt
- 429 Too Many Requests: welke limiet je bezoekers tegenhoudt