Studi Kasus: Ketika OOM Killer Membunuh PHP, Kesalahan Klasik Konfigurasi Memory
Kasus OOM Killer tiba-tiba menghentikan proses PHP sering dianggap sebagai masalah misterius: server terlihat “baik-baik saja”, CPU rendah, tidak ada error fatal di aplikasi, namun proses mati mendadak. Padahal, akar masalahnya hampir selalu sederhana: salah memahami bagaimana memory PHP bekerja dalam konteks banyak worker.
Artikel ini membedah kasus nyata: server 4GB RAM, memory_limit PHP 2GB, dan 20 PHP worker. Di sinilah jebakan klasik terjadi.
Studi Kasus Nyata
Konfigurasi Server
- Total RAM server: 4GB
- PHP
memory_limit: 2GB - PHP-FPM
max_children: 20 - Swap: minim / tidak ada
Gejala yang Terjadi
Proses PHP mati mendadak
Tidak ada fatal error di log PHP
dmesgmenunjukkan:- OOM Killer aktif
- Proses PHP sebagai korban
Log menunjukkan penggunaan memory oleh PHP mencapai ~3GB sebelum kill
Hipotesis Awal
Ada beberapa proses PHP yang secara bersamaan memakan memory besar. Ketika total penggunaan mendekati limit sistem, kernel memilih proses dengan konsumsi terbesar sebagai korban — PHP.
Hipotesis ini terbukti benar.
Kesalahan Paling Umum: Salah Paham memory_limit
Banyak engineer (terutama konfigurasi lama) berpikir:
memory_limit = 2GBartinya PHP secara keseluruhan hanya boleh pakai 2GB.
❌ SALAH BESAR
Fakta Penting
memory_limit adalah:
- Limit per PHP worker / per request
- Bukan limit global
Artinya:
2GB x 20 worker = 40GB potensi alokasi memory
Di server 4GB RAM, ini adalah bom waktu.
Analisa Signal Masalah
PHP Tidak Menunjukkan Error
OOM Killer bekerja di level kernel, bukan aplikasi.
- PHP tidak sempat menulis error
- Request tiba-tiba terputus
Kernel Log adalah Sumber Kebenaran
Cek dengan:
dmesg | grep -i oom
Biasanya terlihat:
- Proses
- PID
- Memory usage terakhir
Memory Naik Bertahap, Bukan Spike
Biasanya disebabkan oleh:
- Request berat
- Data besar
- Leak halus (bukan leak klasik)
Faktor-Faktor yang Memperparah Situasi
Concurrency Tinggi
Beberapa request berat berjalan bersamaan.
Worker PHP Terlalu Banyak
pm.max_childrentinggi- Tidak sebanding dengan RAM
Request PHP Berat
Contoh:
- Export CSV / Excel besar
- Generate PDF
- Image processing
- Query tanpa pagination
Tidak Ada Swap atau Swap Terlalu Kecil
Tanpa swap:
- Kernel tidak punya buffer waktu
- OOM Killer lebih agresif
Memory Fragmentation
PHP + ekstensi native bisa menyebabkan fragmentasi yang sulit ditebak.
Cara Kerja OOM Killer (Ringkas tapi Akurat)
Ketika sistem:
- Hampir kehabisan memory
- Tidak bisa melakukan reclaim
Kernel akan:
Menghitung OOM score setiap proses
Faktor penilaian:
- Penggunaan memory
- Privilege
- Lama hidup proses
Memilih kandidat paling “murah untuk dikorbankan”
Mengirim SIGKILL (tidak bisa ditangkap)
Dalam kasus ini:
PHP adalah proses dengan konsumsi memory terbesar → dieksekusi.
Mengapa Terlihat Mati di ~3GB?
Meskipun RAM 4GB:
- OS butuh memory
- Page cache
- Service lain (Nginx, systemd, dll)
Biasanya:
- 70–80% RAM = zona bahaya
- Di ~3GB → OOM Killer mulai bekerja
Best Practice yang Seharusnya Dilakukan
Turunkan memory_limit
Contoh realistis:
memory_limit = 256M
Ini adalah best practice lama yang justru benar.
Hitung Memory Budget Secara Sadar
Rumus kasar:
(max_children x memory_limit) + overhead < total RAM
Contoh aman:
- 4GB RAM
- 256MB per worker
- max 10–12 worker
Bedakan Request Berat
Pisahkan:
- Web request normal
- Background job (queue, cron, worker khusus)
Jangan jalankan:
- Export besar
- PDF generator
Di PHP web worker biasa.
Gunakan Queue untuk Beban Berat
- Redis / RabbitMQ / SQS
- Worker terkontrol
- Concurrency kecil
Aktifkan Swap (Secukupnya)
Bukan untuk performa, tapi:
- Memberi waktu observasi
- Mencegah kill mendadak
Monitor Memory per Worker
Gunakan:
ps aux --sort -rss- PHP-FPM status page
- APM (New Relic, Datadog)
Pelajaran Penting
memory_limitbukan limit global- PHP worker adalah proses independen
- OOM Killer tidak peduli aplikasi Anda
- Setting besar ≠ aman
- Konfigurasi lama sering salah kaprah
Penutup
Kasus ini adalah contoh klasik bukan bug, tapi miskonsepsi arsitektur.
OOM Killer bukan musuh — ia hanya mengeksekusi keputusan terakhir dari konfigurasi yang keliru.
Jika Anda membaca artikel ini dan masih menggunakan memory_limit 1–2GB untuk PHP web worker: itu bukan optimasi, itu undangan bencana.
Lebih kecil, terkontrol, dan sadar konteks — selalu menang.