Cara Mengatur PHP-FPM agar Website Tahan Trafik Tinggi
Pilih mode pm static, dynamic, atau ondemand, hitung pm.max_children dari RAM, lalu pantau status dan slowlog PHP-FPM sebelum trafik melonjak.
Jawaban singkat
Kunci PHP-FPM tahan trafik adalah pm.max_children yang dihitung dari RAM yang tersedia dibagi rata-rata memori satu proses PHP. Pilih mode pm sesuai pola trafik, nyalakan halaman status dan slowlog, lalu cek log untuk peringatan max_children.
Daftar isi
PHP-FPM adalah pengelola proses PHP yang menerima permintaan dari Nginx atau Apache. Setiap permintaan PHP dikerjakan oleh satu proses anak (worker). Kalau jumlah worker terlalu sedikit, permintaan mengantre dan pengunjung melihat halaman berputar lama atau error 504. Kalau terlalu banyak, RAM habis, server mulai memakai swap, lalu OOM killer mematikan proses penting seperti MySQL.
Jadi pengaturan PHP-FPM bukan soal "makin besar makin bagus". Yang dipertaruhkan adalah keseimbangan antara antrean dan RAM. Angka bawaan dari paket distribusi biasanya dibuat untuk server kecil dan jarang pas untuk situs yang trafiknya tinggi.
Di mana file pengaturannya?
Pengaturan pool ada di file terpisah per pool. Di Ubuntu dan Debian dengan PHP 8.3, file pool bawaan ada di /etc/php/8.3/fpm/pool.d/www.conf. Di AlmaLinux, biasanya /etc/php-fpm.d/www.conf. Satu server bisa punya banyak pool, misalnya satu pool per website, sehingga satu situs yang sibuk tidak menghabiskan worker situs lain.
Setelah mengubah file, uji dan muat ulang:
sudo php-fpm8.3 -t
sudo systemctl reload php8.3-fpm
Membandingkan tiga mode pm
Baris pm menentukan cara PHP-FPM membuat dan mematikan worker. Dokumentasi PHP menyebut tiga pilihan.
static
Jumlah worker tetap sebanyak pm.max_children sejak awal. Tidak ada waktu tunggu untuk membuat proses baru saat trafik datang. Cocok untuk server yang memang khusus menjalankan satu aplikasi PHP dan RAM-nya sudah dihitung.
dynamic
Worker berjumlah di antara pm.min_spare_servers dan pm.max_spare_servers saat sepi, dan bisa naik sampai pm.max_children saat ramai. Ini mode bawaan di banyak distribusi dan pilihan aman untuk kebanyakan VPS yang juga menjalankan database di mesin yang sama.
ondemand
Tidak ada worker sampai ada permintaan. Worker yang menganggur dimatikan setelah pm.process_idle_timeout (bawaannya 10 detik). Hemat RAM untuk banyak situs kecil yang jarang dikunjungi, tapi ada sedikit jeda saat worker baru dibuat.
| Mode | Pemakaian RAM saat sepi | Respons saat lonjakan | Cocok untuk |
|---|---|---|---|
| static | Tetap tinggi | Paling siap | Server khusus satu aplikasi sibuk |
| dynamic | Sedang | Baik, selama batas cukup | VPS umum, aplikasi plus database |
| ondemand | Paling rendah | Ada jeda membuat proses | Banyak situs kecil di satu server |
Bagaimana menghitung pm.max_children?
Ini angka paling penting. Rumusnya sederhana:
pm.max_children = RAM yang disisihkan untuk PHP / rata-rata RAM satu worker
Pertama, lihat rata-rata memori worker saat situs sedang dipakai normal (bukan baru restart):
ps --no-headers -o rss -C php-fpm8.3 | awk '{s+=$1; n++} END {print s/n/1024 " MB"}'
Kedua, tentukan berapa RAM yang boleh dipakai PHP. Kurangi total RAM dengan kebutuhan sistem operasi, database, Redis, dan layanan lain. Lihat angka nyata dengan free -m dan ps aux --sort=-rss | head.
Contoh perhitungan: bila setelah dikurangi semua layanan lain tersisa 2.000 MB untuk PHP, dan rata-rata worker memakai 80 MB, maka pm.max_children sekitar 25. Beri sisa ruang, jangan pas di batas, karena ada worker yang sesekali memakai memori jauh di atas rata-rata (misalnya saat ekspor laporan atau memproses gambar).
Untuk mode dynamic, isi juga angka spare. Dokumentasi PHP menyebut nilai bawaan pm.start_servers adalah min_spare_servers + (max_spare_servers - min_spare_servers) / 2. Contoh yang wajar untuk max_children 25:
pm = dynamic
pm.max_children = 25
pm.start_servers = 6
pm.min_spare_servers = 4
pm.max_spare_servers = 8
pm.max_requests = 500
pm.max_requests membuat worker di-restart setelah melayani sejumlah permintaan. Ini menahan efek kebocoran memori dari plugin atau ekstensi. Nilai bawaannya 0, artinya tidak pernah di-restart.
Kapan memilih yang mana?
Pilih static bila server memang untuk satu aplikasi, RAM sudah dihitung, dan kamu ingin respons paling stabil saat trafik datang tiba-tiba. Pilih dynamic bila database dan layanan lain berbagi RAM yang sama, karena worker berkurang saat sepi dan memberi ruang ke yang lain. Pilih ondemand untuk server yang menampung banyak situs kecil dengan satu pool per situs.
Apa pun modenya, PHP-FPM tidak bisa menutupi aplikasi yang lambat. Kalau setiap permintaan butuh beberapa detik karena query database berat, menambah worker hanya menambah antrean di database. Cek juga OPcache PHP dan page cache sebelum menaikkan angka worker.
Memantau dan membaca tanda bahaya
Nyalakan halaman status dan slowlog di file pool:
pm.status_path = /fpm-status
slowlog = /var/log/php8.3-fpm-slow.log
request_slowlog_timeout = 5s
Halaman status menampilkan jumlah worker aktif, antrean (listen queue), dan max children reached. Batasi aksesnya di Nginx hanya untuk 127.0.0.1. Slowlog mencatat jejak fungsi untuk permintaan yang lebih lama dari 5 detik, sehingga kamu tahu bagian kode mana yang lambat.
Pesan ini di log PHP-FPM adalah tanda paling jelas bahwa worker kurang:
WARNING: [pool www] server reached pm.max_children setting (25), consider raising it
Kalau pesan itu muncul tapi RAM sudah mepet, solusinya bukan menaikkan angka, melainkan mempercepat aplikasi, memasang cache, atau menambah RAM VPS.
Pertanyaan yang sering diajukan
Apakah setiap website perlu pool sendiri?
Disarankan bila satu server menampung beberapa situs. Pool terpisah bisa memakai user Linux berbeda dan batas worker sendiri, sehingga satu situs yang sibuk atau diretas tidak langsung mengganggu situs lain.
Lebih baik koneksi Nginx ke PHP-FPM lewat socket atau TCP?
Bila keduanya di server yang sama, Unix socket umum dipakai dan sedikit lebih ringan. TCP diperlukan bila PHP-FPM berada di server atau container berbeda.
Apakah mengubah pengaturan pool memutus pengunjung?
Perintah reload membuat PHP-FPM mengganti worker secara bertahap. Tetap lakukan di jam sepi dan uji konfigurasi dengan opsi -t terlebih dulu.
Berapa nilai request_terminate_timeout yang aman?
Sesuaikan dengan proses terlama yang memang wajar di aplikasimu, dan samakan dengan batas timeout di Nginx. Nilai terlalu kecil memutus proses sah seperti impor data, nilai 0 membuat proses macet bisa menahan worker selamanya.


