Max Execution Time WordPress: Fatal Error 30 Detik, set_time_limit, dan Rantai Timeout Server

9 menit baca
Max Execution Time WordPress: Fatal Error 30 Detik, set_time_limit, dan Rantai Timeout Server

Layar merah bertuliskan Fatal error: Maximum execution time of 30 seconds exceeded muncul saat WP All Import memproses ribuan baris produk. Skenario lebih membingungkan: max_execution_time sudah dinaikkan ke 300, tetapi browser menampilkan 504 Gateway Timeout di detik 60. Forum menyuruh ubah angka di php.ini, padahal ada counter yang menipu dan rantai lapisan yang punya jam pasir sendiri. Panduan ini membedah cara counter menghitung waktu, perilaku set_time_limit() yang me-reset hitungan, dan peta rantai timeout dari script PHP sampai edge CDN.

Apa Itu Max Execution Time dan Kenapa PHP Membatasi Waktu Script?

max_execution_time adalah directive PHP yang membatasi berapa lama satu script boleh berjalan dalam satu request, dengan nilai default 30 detik menurut dokumentasi resmi PHP. Nilai ini dibaca dari php.ini dan bisa di-override per direktori lewat .user.ini, per request lewat set_time_limit(), atau per skrip lewat ini_set. Satuannya detik, dan hitungannya dimulai saat script mulai dieksekusi.

Tujuannya proteksi. Tanpa batas ini, satu script liar yang terjebak loop tak berujung akan mengunci satu worker selamanya. Istilah timeout di sini berarti pemutus darurat yang mengorbankan satu request demi antrean di belakangnya.

Posisinya dalam klaster performa adalah sumbu durasi. Jumlah worker menentukan berapa proses hidup berdampingan, memory limit menentukan berapa besar memori tiap proses, dan batas inilah yang menentukan berapa lama tiap proses boleh berjalan. Tiga sumbu ini saling mengunci.

Perbedaan max_execution_time dan set_time_limit(): Reset Counter dan Trik Loop Plugin

Pembahasan max_execution_time vs set_time_limit selalu kembali ke fakta yang jarang ditulis tutorial lokal. Memanggil set_time_limit() memang setara mengubah directive untuk proses berjalan, tetapi ia juga me-reset counter dari nol. Counter 30 detik yang sudah berjalan 29 detik kembali ke nol begitu fungsi dipanggil ulang.

Inilah trik plugin import dan backup. Di tiap iterasi loop, plugin memanggil set_time_limit(30) sehingga tiap batch mendapat jatah 30 detik segar. Mekanismenya legal dan didokumentasikan.

Pasangannya yang berbahaya adalah set_time_limit(0) yang berarti tanpa batas. Satu loop nakal mengunci satu worker PHP selamanya, paralel bahaya memory_limit -1 di artikel WP Memory Limit WordPress. Istilah long-running task yang sah selalu memakai angka konkret, bukan nol.

Fatal Error Maximum Execution Time of 30 Seconds Exceeded: Penyebab dan Mitos

Frasa pencarian maximum execution time of 30 seconds exceeded wordpress hampir selalu muncul setelah operasi berat yang sah. WP All Import memproses ribuan baris CSV dalam satu request, plugin backup menjalankan dump database penuh, image optimizer mengompres ratusan gambar sekaligus, update massal plugin dan tema berjalan berurutan, atau WooCommerce memproses order dalam batch besar. Semua skenario ini mengeksekusi script PHP murni dalam waktu lama.

Mitosnya berbunyi tinggal naikkan angka maka semua beres. Kenyataannya ada dua titik gagal. Pertama, lapisan lain lebih pendek sehingga request mati sebelum limit PHP tercapai. Kedua, script memang bermasalah sehingga kenaikan limit hanya menunda error.

Sejak WordPress 5.2 ada konteks tambahan berupa fatal error protection dan recovery mode yang mencoba menangkap error fatal dan memberi tautan pemulihan ke dashboard. Fitur ini membantu pemilik situs masuk kembali setelah error, tetapi tidak menambah waktu eksekusi satu detik pun.

Yang Dihitung Counter: Waktu CPU, Bukan Tunggu Query dan I/O

Fakta inti yang mengubah cara diagnosis: max_execution_time hanya menghitung waktu eksekusi script di CPU. Waktu menunggu query database, I/O file, sleep, dan stream ke API eksternal tidak masuk counter sama sekali. Counter berhenti berputar selama script menunggu, lalu lanjut lagi saat CPU kembali bekerja.

Konsekuensinya dua arah. Website lambat karena query berat bisa tidak pernah memicu error ini, karena penantiannya tidak dihitung. Sebaliknya loop PHP murni mati tepat di detik 30. Kalau website lambat tanpa error, curigai waktu tunggu dan baca artikel InnoDB Buffer Pool WordPress.

Diagram berikut memvisualkan request 90 detik yang hanya menghabiskan 8 detik jatah counter.

Diagram timeline satu request 90 detik dengan 8 detik eksekusi CPU yang dihitung counter berbanding 82 detik tunggu database API dan I/O yang tidak dihitung

Cara Mendiagnosis dan Mengatur Batas Waktu Eksekusi dengan Aman

Diagnosis mendahului perubahan. Alurnya tiga tahap: cek nilai aktif, identifikasi pemicu, terapkan di lapis yang benar. Gejala menentukan lapis yang disentuh, karena fatal error versus 502 versus 504 menunjuk lapisan berbeda.

Mengecek Nilai Aktif via phpinfo, php -i, dan WP-CLI

Nilai max_execution_time bisa berbeda antara CLI dan web, jadi catat keduanya sebelum mengubah apa pun. Perintah berikut membaca nilai global dari terminal dan nilai runtime yang dikenali WordPress saat proses berjalan.

php -i | grep max_execution_time
wp eval 'echo ini_get("max_execution_time");'

Verifikasi silang lewat fungsi phpinfo() di berkas info sementara atau halaman Site Health untuk nilai runtime aktual. Jika angka CLI dan web berbeda, yang berlaku untuk pengunjung adalah nilai web, bukan nilai terminal.

Mengidentifikasi Operasi dan Plugin Pemicu Timeout

Cocokkan momen error dengan operasi yang sedang berjalan: import, backup, optimizer gambar, atau update massal. Uji ulang dengan plugin non-inti dimatikan dan tema default dipakai, lalu baca jejak stack trace di error log untuk menemukan fungsi yang memakan waktu.

Jika waktu habis di tunggu query database, solusinya bukan menaikkan limit melainkan optimasi query dan cache. Menaikkan limit hanya tepat bila script PHP sah yang berat terbukti menjadi penyebab dari jejak log.

Menerapkan Nilai Baru di Lapis yang Tepat

Urutannya: fungsi per-site dulu, konfigurasi PHP global kemudian, proxy dan FPM untuk pemilik VPS, lalu hubungi hosting untuk lapis yang dikunci. Nilai wajar rutin adalah 60 sampai 120 detik, 300 detik hanya untuk import atau backup sesekali.

set_time_limit(300); // di wp-config.php, sebelum memuat WordPress
ini_set('max_execution_time', '300'); // setara, tanpa me-reset di tengah loop

Setelah menyimpan, ulangi operasi pemicu dan pastikan error hilang tanpa gejala baru. Jika error berubah menjadi 504, masalah berpindah ke lapisan proxy dan perlu penyelarasan timeout proxy bukan kenaikan limit PHP lanjutan.

Rantai Timeout Server Berlapis: fastcgi_read_timeout, request_terminate_timeout, hingga 504

Satu request dinamis melewati lapis-lapis yang masing-masing punya jam pasir sendiri dan berlaku independen satu sama lain. Edge CDN menunggu origin, nginx menunggu upstream PHP-FPM, PHP-FPM mengawasi umur worker, script PHP menghitung jatah CPU, dan MariaDB menjaga koneksinya. Lapis terpendek menentukan kapan request mati dan jenis error apa yang diterima pengunjung.

Contoh klasik: max_execution_time 300 detik tidak berguna bila nginx memutus di detik 60. Antrean worker yang tertekan saat script lama menumpuk dibahas di artikel PHP Worker WordPress, sedangkan peran proxy dan edge dipetakan di artikel Reverse Proxy dan Load Balancer.

LapisanParameter KunciDiatur di ManaDefault UmumPerilaku Saat Terlampaui
PHP scriptmax_execution_timephp.ini, .user.ini, wp-config via set_time_limit()30 detik menurut dokumentasi resmi PHPFatal error Maximum execution time exceeded di dalam halaman
PHP-FPM poolrequest_terminate_timeoutkonfigurasi pool seperti www.confmati atau nol pada banyak build umumWorker dihentikan paksa dan muncul sebagai 502 dari sisi proxy
nginx reverse proxyfastcgi_read_timeout dan proxy_read_timeoutnginx.conf atau server block60 detik pada banyak build umumKoneksi ke upstream diputus dan pengunjung menerima 504 Gateway Timeout
Edge CDN atau proxy luarbatas waktu proxy per penyediapanel CDNsekitar 100 detik pada paket umumError 524 atau 504 dari edge sebelum origin selesai bekerja
MariaDBwait_timeout untuk koneksi idle dan max_statement_time untuk durasi statementmy.cnfwait_timeout 28800 detik dan max_statement_time nol atau tanpa batasKoneksi diputus atau statement dibatalkan dan PHP melihat kegagalan query

Seluruh nilai default di atas adalah perkiraan umum hasil verifikasi dokumentasi resmi masing-masing proyek, dan bisa berbeda per build serta paket hosting.

max_execution_time = 300      # php.ini, jatah script
fastcgi_read_timeout 300s;    # nginx, selaras dengan jatah script
request_terminate_timeout = 300s  # PHP-FPM pool, selaras dengan keduanya
Gejala yang TerlihatLapisan yang TerlampauiTindakan yang Tepat
Fatal error Maximum execution time exceeded tampil di halaman atau logmax_execution_time PHPPeriksa apakah script memang berat, naikkan nilai untuk operasi sah, atau perbaiki loop plugin yang cacat
504 Gateway Timeout setelah sekitar 60 detikfastcgi_read_timeout atau proxy_read_timeout nginx, atau edge CDN bila lebih cepatSelaraskan timeout proxy dengan max_execution_time dan jangan hanya ubah php.ini
502 Bad Gateway setelah proses berjalan lamarequest_terminate_timeout PHP-FPM membunuh workerNaikkan batas terminasi FPM atau pecah pekerjaan menjadi batch lebih kecil
Query gagal atau koneksi database hilang di tengah proseswait_timeout atau max_statement_time MariaDBOptimasi query dengan indeks dan cache baca artikel InnoDB Buffer Pool WordPress
Diagram rantai timeout satu request dari edge CDN ke nginx ke PHP-FPM ke script PHP ke MariaDB dengan nginx sebagai lapis terpendek yang memutus di detik 60
Rantai timeout hanya sekuat lapis terpendeknya. Menaikkan satu angka di php.ini tidak menolong bila jam pasir di nginx atau edge proxy habis lebih dulu; ubah lapis yang benar, bukan lapis yang paling mudah dijangkau.

Max Execution Time dalam Peta Klaster: PHP Worker, WP-Cron, dan Fatal Error Memori

Durasi hanyalah satu variabel kapasitas server. Pasangan fatal error terdekatnya adalah memory limit, dibahas berpasangan di artikel WP Memory Limit WordPress yang terbit sehari sebelum artikel ini. Script lama mengikat worker lebih lama sehingga antrean memanjang pada jam sibuk.

Korban paling sering adalah WP-Cron yang berjalan dalam request PHP biasa, solusinya pindah ke cron sistem seperti dibahas di artikel Disable WP-Cron. Kebutuhan limit ikut turun bila eksekusi dipercepat lewat OPcache WordPress dan Redis Object Cache WordPress.

Rekomendasi Hosting untuk Operasi Berat dan Long-Running Task

Mayoritas website cukup di Cloud Hosting Mordenhost yang memberi batas waktu wajar terkelola plus dukungan diagnosis timeout saat error muncul.

Workflow rutin import besar, backup dalam dashboard, atau batch WooCommerce skala besar butuh ruang hitung sendiri. Managed VPS Mordenhost memberi tuning enterprise rantai timeout lintas lapis. Jeda respons dinamis bisa dipantau lewat TTFB WordPress sebelum naik kelas.

Kesimpulan

Batas waktu eksekusi hanyalah satu lapis rantai. Baca gejala dulu, identifikasi lapis yang tersandera, baru ubah nilainya. Kalau fondasi server masih kabur, baca dulu memahami cara kerja hosting.

Pertanyaan yang Sering Ditanya

Empat jawaban singkat untuk pertanyaan paling umum soal nilai aman, timeout yang bandel, fungsi tanpa batas, dan WP-Cron.

Berapa nilai max_execution_time yang disarankan untuk WordPress?

Mayoritas situs nyaman di 60 sampai 120 detik untuk operasional harian normal. Nilai 300 detik hanya untuk operasi sesekali seperti import besar atau backup. Hindari nilai nol atau ratusan ribu karena membuang proteksi worker.

Kenapa nilai sudah dinaikkan ke 300 tapi masih timeout?

Ada dua kemungkinan: lapisan lain seperti nginx, PHP-FPM, atau edge CDN memutus lebih cepat, atau waktu habis di tunggu query yang tidak dihitung counter ini.

Apakah set_time_limit(0) aman dipakai di produksi?

Tidak aman untuk produksi karena satu proses boleh berjalan selamanya tanpa pemutus darurat. Saat loop bermasalah terjadi, satu worker terkunci permanen dan kapasitas server berkurang. Tetapkan angka konkret sesuai operasi terberat situsmu.

Apakah max_execution_time berlaku untuk WP-Cron?

Berlaku, karena task WP-Cron berjalan dalam request PHP biasa dengan batas yang sama. Task berat sebaiknya dipindah ke cron sistem agar tidak tersandera batas eksekusi request web. Detail migrasi ada di artikel Disable WP-Cron.

Butuh bantuan membaca hasil diagnosis timeout situsmu? Hubungi WhatsApp Mordenhost atau portal tiket dan tim kami membantu memetakan lapis yang tersandera serta paket yang pas.

TM
Tim Mordenhost
Editorial