De fout in z'n volle vorm:
Fatal error: Maximum execution time of 30 seconds exceeded
in /home/site/wp-content/plugins/example/import.php on line 142
Drie dingen om hieruit te lezen vóórdat je iets verhoogt:
- De limiet zelf: 30 seconden in dit voorbeeld. Defaults variëren tussen hosters — veel zien
30(PHP-default),60(gemiddeld) of120-300(WordPress-friendly hosting). - Het bestand en de regel:
plugins/example/import.phpregel 142. Dáár liep PHP vast — meestal de plek waar een query, een loop of een externe API-call hangt. - De context: gebeurt het op een willekeurige frontend-pagina of alleen tijdens een specifieke admin-actie (import, plugin-update, backup, image-bewerking)? Dat verschil bepaalt of je de limiet moet verhogen of het script moet repareren.
Wat is max_execution_time eigenlijk?
Het is de PHP-instelling die zegt: één PHP-script (één pageload of cron-job) mag maximaal X seconden actief draaien. Niet voor de hele site, niet voor alle bezoekers samen — per request. PHP houdt CPU-tijd bij; als het over de limiet gaat, wordt het script direct afgebroken met een fatal error.
De PHP-default is 30 seconden. Hosters zetten 'm vaak hoger (60–300 seconden voor WordPress-hosting), maar shared hosting van de zuinige soort zit nog op 30. Op de CLI (cron-jobs, WP-CLI) is de default vaak 0 (oneindig) — daarom hebben cron-imports zelden last van deze fout.
Stap 1: voor je iets verhoogt — diagnose
De grootste fout die ik klanten zie maken: meteen set_time_limit(0) in wp-config.php plakken. Drie keer op de tien lost dat het probleem niet op — het verbergt het alleen. Beantwoord eerst:
1. Wanneer verschijnt de fout?
- Tijdens een specifieke import / export / backup / migratie → vaak terecht: zware operatie heeft tijd nodig. Verhogen is gerechtvaardigd, maar overweeg ook batch-verwerking.
- Tijdens plugin-update of WordPress core-update → meestal trage download van plugin-zip vanaf wordpress.org of langzame remote-extractie. Verhoging tot 300s is een prima fix.
- Op een willekeurige frontend-pagina, vaak met dezelfde plugin in 't trace → rode vlag. Een frontend-pagina hoort onder de 5 seconden te blijven. Niet de limiet verhogen, maar het script onderzoeken.
- Pas verschenen na een update → de update is de oorzaak. Rollback of plugin/theme-update onderzoeken.
2. Wat zegt het error_log?
Niet alleen de laatste regel kijken — vaak staan er vóór de fatal error waarschuwingen die de oorzaak verraden. Bijvoorbeeld een cURL timeout-warning betekent dat het script wachtte op een externe API die niet antwoordde. Een MySQL slow query betekent dat een database-vraag lang duurde. Dat zijn echte oorzaken, geen tijdslimiet-probleem.
3. Heeft de site recent veranderingen ondergaan?
Plugin update, theme update, hoster die PHP heeft bijgewerkt, externe API die kapot is, of een DB die langzamer geworden is door dataset-groei. Alle vier triggeren execution-time fouten zonder dat de PHP-config is gewijzigd.
Stap 2: max_execution_time verhogen — per locatie
Heb je vastgesteld dat verhogen gerechtvaardigd is, dan zijn dit de plaatsen waar je het kunt doen. In volgorde van wat je het eerste probeert:
WordPress: wp-config.php
// Boven de regel "/* That's all, stop editing! */"
set_time_limit(300);
// Of via ini_set:
@ini_set('max_execution_time', 300);
Werkt alleen als je hoster set_time_limit() en ini_set() niet heeft uitgeschakeld. Sommige zuinige shared hosters blokkeren deze functies waardoor je code stilletjes wordt genegeerd.
Universeel: .htaccess (Apache)
php_value max_execution_time 300
php_value max_input_time 300
Werkt alleen op Apache met mod_php (klassieke shared hosting). Op modern PHP-FPM of Nginx negeert de webserver deze regels of geeft 500-error. Test direct na toevoegen.
Universeel: .user.ini (PHP-FPM)
; Plaats dit bestand in de WordPress-root
max_execution_time = 300
max_input_time = 300
Op moderne shared hosting (cPanel, DirectAdmin, Plesk met PHP-FPM) is .user.ini de juiste plek. Aanpassingen worden elke 5 minuten opnieuw geladen door PHP-FPM; soms moet je wachten of FPM laten herstarten.
Eigen VPS / cPanel MultiPHP: php.ini
max_execution_time = 300
max_input_time = 300
memory_limit = 256M
De hoogste prioriteit — deze instellingen overrulen alles wat in .htaccess of .user.ini staat. In cPanel vind je dit onder "MultiPHP INI Editor". In DirectAdmin onder "PHP Selector". Op een eigen VPS is het /etc/php/X.Y/fpm/php.ini.
Cron-jobs: aparte instelling
Cron draait via PHP-CLI — een aparte php.ini dan webrequests (typisch in /etc/php/X.Y/cli/php.ini). Heeft het webgedeelte 300s en cron 30s, dan klapt je geplande backup om 3:00 stilletjes uit. Check met php --ini welke ini-files actief zijn voor de CLI.
Wat als je hoster niets toestaat?
Bij sommige zuinige shared hosters (typisch onder €5/maand) staat alles op slot — geen php_value in .htaccess, geen .user.ini die wordt gerespecteerd, en set_time_limit() functioneel uitgeschakeld. Je opties:
- Hoster mailen en vragen of ze de limiet voor jou kunnen verhogen. Lukt vaak voor €0,- als je een legitieme reden hebt.
- Switch naar een betere hoster. Voor €7–10/maand krijg je hosting waar PHP-instellingen wel aanpasbaar zijn (Hostnet, TransIP, Vimexx, Combell).
- De zware operatie buiten WordPress doen. Een import van 50.000 producten kun je via WP-CLI op de server draaien (geen webrequest, dus geen execution-time-limiet). Of via een offline tool zoals MySQL Workbench die rechtstreeks tabellen leest.
Wanneer de fout een symptoom is, geen oorzaak
Drie scenario's waarin verhogen het probleem alleen verschuift:
Een query zonder index op een grote tabel
WordPress' wp_options-tabel kan opzwellen tot honderden megabytes door autoload-data van slecht-gebouwde plugins. Een gewone SELECT * FROM wp_options WHERE autoload='yes' wordt dan ineens een 8-seconden-query. Op elke pageload. Verhoog je dan naar 300s, dan wordt elke pageload nog steeds 8 seconden traag — je hebt het probleem niet opgelost. Lees: wp_options autoload — waarom je site na 2 jaar trager wordt.
Een externe API die hangt
Plugins die op elke pageload een externe API aanroepen (geocoding, currency-conversie, social media-feeds) kunnen je site stoppen als die API traag is. Fix: caching toevoegen (transients in WordPress, of een dedicated cache-laag) zodat de externe call eens per uur gebeurt in plaats van elke pageload.
Een loop die te ver gaat
Een plugin die alle 100.000 posts ophaalt om er één actie op uit te voeren. Of een nieuwsbrief-tool die alle 50.000 abonnees in één script wil verzenden. Voor zulke operaties is batching de fix: verwerk per 100 of 500, sla voortgang op, herhaal in een cron-cyclus. Een korte execution-time afdwingen is je vriend hier, niet je vijand — het dwingt je tot beter ontwerp.
Veelgestelde vragen
Wat is het verschil met "504 Gateway Timeout"?
Beide gaan over te-lange verwerking, maar van verschillende kanten. Maximum execution time exceeded komt van PHP zelf: PHP merkt dat z'n script te lang draait en stopt het. 504 Gateway Timeout komt van een proxy (Nginx, Cloudflare) die te lang heeft gewacht op een antwoord van PHP. Vaak verschijnt 504 omdat PHP nog z'n werk doet (max_execution_time hoger dan de proxy-timeout). Lees: 504 Gateway Timeout oplossen.
Mag ik set_time_limit(0) gebruiken?
Voor cron-jobs en CLI-scripts: ja, daar is het OK. Voor frontend-pageloads: liever niet — een hangende script kan je server-resources opslokken zonder dat je 't merkt. Geef altijd een specifieke maximum (300, 600) zodat een echt-vastgelopen script alsnog opbreekt.
Hoe meet ik hoe lang m'n PHP-scripts draaien?
WordPress > Tools > Site Health geeft de gemiddelde server response time. Voor diepere analyse: Query Monitor plugin (geeft ms per query), of New Relic / Tideways APM (production-grade). Voor éénmalige meting: voeg microtime(true) toe aan het begin en eind van een verdacht script.
Werkt set_time_limit() bij elke iteratie van een loop?
Ja. set_time_limit(60) zet de teller terug op 60 seconden vanaf het moment dat 't wordt aangeroepen. In een import-loop kun je dus elke iteratie set_time_limit(60) doen, en zolang elke iteratie binnen 60s blijft, valt de loop nooit om — ook al draait de hele operatie 30 minuten. Goede techniek voor lange imports.
Kan ik de limiet verhogen voor één specifieke pagina?
Ja, in WordPress kun je in een specifieke template-functie of in een plugin set_time_limit(300) aanroepen vóór de zware actie. Effectief voor één pageload, daarna is de site weer terug op de standaard limiet. Bouw zo geen "dynamische exception" voor een dieper probleem — gebruik het alleen voor legitieme zware acties.
Snel overzicht: locatie van instellingen per hoster-type
- Shared hosting met cPanel: MultiPHP INI Editor →
max_execution_time - Shared hosting met DirectAdmin: PHP Selector → PHP options
- Shared hosting met Plesk: Hosting Settings → PHP Settings
- Shared hosting Antagonist / Yourhosting:
.user.iniin webroot - Hostnet / TransIP managed: control panel → PHP-instellingen
- Combell / one.com: control panel → PHP → max_execution_time
- Eigen VPS:
/etc/php/X.Y/fpm/php.inien daarnasystemctl reload php-fpm
Twijfel je waar je het kunt aanpassen op jouw hoster? Mail de support van je hoster met de fout-melding — ze kennen hun eigen panel beter dan een algemene gids.