📑 Daftar Isi
- Apa Itu Memory Cgroup Out of Memory?
- Membaca Log Error dengan Benar
- Kenapa Ini Terjadi? Root Cause yang Sebenarnya
- 1. Memory Cgroup Limit Terlalu Kecil
- 2. PHP Memory Limit Terlalu Tinggi
- 3. Traffic Spike / Bot Attack
- 4. Memory Leak di Aplikasi PHP
- 5. Worker PHP Multiplying
- Cara Cek Memory Cgroup Limit
- Solusi Step-by-Step
- Solusi 1: Tingkatkan Memory Cgroup Limit
- Solusi 2: Turunkan PHP Memory Limit
- Solusi 3: Batasi PHP Worker Multiplying
- Solusi 4: Identifikasi User yang Boros Memori
- Solusi 5: Monitor dengan Script Otomatis
- Troubleshooting Table
- Pro Tips dari NOC Engineer
- Kapan Harus Naikkan RAM vs Naikkan Cgroup Limit?
- FAQ
- Q: Apakah Memory Cgroup Out of Memory sama dengan OOM Killer biasa?
- Q: Kenapa proses lsphp yang dibunuh, bukan proses lain?
- Q: Bagaimana cara mencegah OOM tanpa menambah RAM atau naikkan limit?
- Q: Apakah aman menonaktifkan OOM cgroup killer?
- Related Issues
Saya pernah dapat panicked call jam 5 pagi dari client yang bilang websitenya down. Semua halaman PHP cuma muncul 500 error. Saya langsung SSH ke server, cek logs, dan nemu baris-baris ini yang panik banget di /var/log/messages:
Jul 26 05:49:06 manaslu kernel: Memory cgroup out of memory: Killed process 4109148 (lsphp) total-vm:714676kB, anon-rss:98908kB, file-rss:19900kB, shmem-rss:4kB, UID:3002 pgtables:828kB oom_score_adj:0
Jul 26 05:49:08 manaslu kernel: Memory cgroup out of memory: Killed process 4109124 (lsphp) total-vm:718772kB, anon-rss:101812kB, file-rss:19900kB, shmem-rss:4kB, UID:3002 pgtables:836kB oom_score_adj:0
Jul 26 05:49:09 manaslu kernel: Memory cgroup out of memory: Killed process 4109128 (lsphp) total-vm:723000kB, anon-rss:107620kB, file-rss:19900kB, shmem-rss:4kB, UID:3002 pgtables:848kB oom_score_adj:0
Jul 26 05:49:10 manaslu kernel: Memory cgroup out of memory: Killed process 4109126 (lsphp) total-vm:731192kB, anon-rss:115864kB, file-rss:19900kB, shmem-rss:4kB, UID:3002 pgtables:864kB oom_score_adj:0
Waktu itu saya langsung mikir: “Ini bukan soal RAM server habis secara keseluruhan — ini soal memory cgroup.” Dan banyak admin yang salah paham soal ini. Mereka langsung panic, tambah RAM, padahal masalahnya beda total.
Ibarat kamu punya kamar kos yang cuma muat kasur + meja. Kamu beli lemari baru, tapi kamarnya tetap kecil — lemari barunya nggak muat karena batas ukuran kamarnya yang jadi masalah, bukan jumlah barangmu. Itulah yang terjadi di memory cgroup.
Apa Itu Memory Cgroup Out of Memory?
Memory cgroup (atau memcg) adalah fitur kernel Linux yang membatasi berapa banyak RAM yang boleh dipakai oleh sekumpulan proses tertentu. Di server shared hosting yang pakai CloudLinux atau CageFS, setiap user dibatasi memory cgroup-nya — supaya satu user yang boros RAM nggak menghancurkan user lain.
Ketika proses lsphp (LiteSpeed PHP) melebihi batas memory cgroup yang ditetapkan, kernel langsung bunuh proses tersebut — dan kamu lihat log error di atas. Prosesnya dibunuh paksa, bukan crash sendiri.
Membaca Log Error dengan Benar
Ini bagian yang sering dilewatkan. Setiap baris di log punya cerita. Mari kita bedah satu per satu:
Jul 26 05:49:06 manaslu kernel: Memory cgroup out of memory: Killed process 4109148 (lsphp) total-vm:714676kB, anon-rss:98908kB, file-rss:19900kB, shmem-rss:4kB, UID:3002 pgtables:828kB oom_score_adj:0
Penjelasan per field:
| Field | Nilai | Artinya |
|---|---|---|
Memory cgroup out of memory |
— | Ini OOM berbasis cgroup, bukan OOM system-wide |
Killed process 4109148 |
PID | ID proses yang dibunuh kernel |
(lsphp) |
Process name | LiteSpeed PHP worker — ini yang melayani request PHP |
total-vm:714676kB |
~698 MB | Total virtual memory yang dialokasikan proses |
anon-rss:98908kB |
~96 MB | Memory anonim (heap) yang benar-benar dipakai — ini yang paling penting |
file-rss:19900kB |
~19 MB | Memory yang dipakai untuk file mapping (cache file) |
shmem-rss:4kB |
~4 KB | Shared memory — hampir nol di sini |
UID:3002 |
User ID | ID user hosting yang proses PHP-nya dibunuh |
pgtables:828kB |
Page tables | Memory untuk page table mappings |
oom_score_adj:0 |
0 | Default score — tidak ada preferensi pembunuhan |
Nah, yang paling kritis dari log ini adalah: proses yang dibunuh adalah lsphp. Itu artinya worker PHP LiteSpeed sedang melayani request dan terbunuh di tengah jalan. Hasilnya? Client dapat 500 error atau connection reset.
Kenapa Ini Terjadi? Root Cause yang Sebenarnya
Ada beberapa kemungkinan, dan kita perlu eliminasi satu per satu:
1. Memory Cgroup Limit Terlalu Kecil
Ini penyebab paling umum. Di CloudLinux, default memory limit per user bisa sangat rendah — kadang cuma 256MB atau 512MB. Kalau website client pakai WordPress dengan banyak plugin berat (WooCommerce, page builder, caching plugin), limit itu gampang sekali terlampaui.
2. PHP Memory Limit Terlalu Tinggi
Ironisnya, kalau kamu set memory_limit di PHP terlalu tinggi (misal 512MB atau 1024MB), tapi memory cgroup limit-nya cuma 512MB — kamu sudah membuat bom waktu. PHP boleh minta sampai 512MB, tapi cgroup cuma izinkan 512MB total untuk semua proses user itu.
3. Traffic Spike / Bot Attack
Log di atas menunjukkan 4 proses lsphp terbunuh dalam rentang 4 detik (05:49:06 sampai 05:49:10). Ini pattern khas: banyak worker PHP aktif bersamaan, masing-masing makan memori, dan akhirnya cgroup limit mentok.
4. Memory Leak di Aplikasi PHP
Kadang ada plugin atau custom script yang bocor memori — setiap request sedikit demi sedikit menambah penggunaan memori tanpa pernah dilepas.
5. Worker PHP Multiplying
LiteSpeed PHP worker bisa spawn banyak child process. Kalau max children terlalu banyak, total konsumsi memori melebihi cgroup limit.
Cara Cek Memory Cgroup Limit
Sebelum lanjut ke solusi, kita perlu tahu dulu berapa limit yang aktif:
# Cek memory limit untuk user tertentu
cat /sys/fs/cgroup/memory/user/3002/memory.limit_in_bytes
# Cek penggunaan memori saat ini
cat /sys/fs/cgroup/memory/user/3002/memory.usage_in_bytes
# Cek di CloudLinux (path berbeda)
cat /proc/user/3002/resource_limits 2>/dev/null || cat /sys/fs/cgroup/memory/user.slice/user-3002.slice/memory.limit_in_bytes
Atau kalau kamu pakai CloudLinux dengan LVE Manager:
# Cek limits via lvesectl
lvesectl limits --lve-id=3002
# Atau via cPanel stats
cat /var/cpanel/databases.db | grep -i memory
Kalau kamu lihat limit-nya 256MB atau 512MB, itu sudah jelas kenapa lsphp dibunuh — limitnya terlalu kecil untuk workload website tersebut.
Solusi Step-by-Step
Solusi 1: Tingkatkan Memory Cgroup Limit
Ini solusi paling langsung. Kalau user butuh lebih banyak RAM, naikkan limitnya.
Untuk CloudLinux LVE:
# Naikkan memory limit untuk user tertentu (dalam MB)
lvesectl set --lve-id=3002 --mem=2048
# Atau via WHM > CloudLinux LVE Manager > Users
# Cari user, edit memory limit, save
Untuk LiteSpeed Enterprise:
# Edit config LiteSpeed
cd /usr/local/lsws/conf/
nano httpd.conf
# Cari bagian vhost atau pool, atur memory limit
# Contoh untuk virtual host:
vhTemplate lsphp {
memHardLimit 2048M
memSoftLimit 1536M
}
# Restart LiteSpeed
systemctl restart lsws
⚠️ Peringatan: Jangan naikkan limit terlalu tinggi sekaligus. Naikkan bertahap — 512MB → 1024MB → 2048MB — dan monitor selama 24-48 jam sebelum naik lagi.
Solusi 2: Turunkan PHP Memory Limit
Jika memory cgroup limit tidak bisa dinaikkan (misal karena server sudah padat), kamu perlu turunkan memory_limit di PHP supaya tidak terjadi konflik.
# Cek memory_limit saat ini
php -i | grep memory_limit
# Atau per user
cat /home/user/.php/php.ini | grep memory_limit
# Edit php.ini (global atau per user)
nano /opt/lsws/lsphp81/etc/php.ini
# Set memory_limit yang realistis
memory_limit = 256M
# Restart LiteSpeed
systemctl restart lsws
Rule of thumb: PHP memory_limit sebaiknya tidak lebih dari 60-70% dari memory cgroup limit. Kalau cgroup limit 1024MB, set PHP memory_limit di 512-768MB max.
Solusi 3: Batasi PHP Worker Multiplying
LiteSpeed PHP worker punya setting untuk membatasi jumlah child process. Kalau ini tidak dibatasi, satu user bisa men-spawn puluhan worker yang masing-masing makan banyak RAM.
# Cek jumlah worker yang aktif
ps aux | grep lsphp | grep -c ""
# Batasi max children di LiteSpeed config
# Edit httpd.conf
cd /usr/local/lsws/conf/
nano httpd.conf
# Tambahkan setting ini di virtual host:
vhTemplate lsphp {
maxConns 35
env PHP_LSAPI_CHILDREN 35
memSoftLimit 1024M
memHardLimit 1280M
}
# Restart
systemctl restart lsws
Solusi 4: Identifikasi User yang Boros Memori
Kalau ini server shared hosting, kamu perlu tahu siapa yang makan banyak memori:
# Tampilkan proses yang pakai memori paling banyak, urut dari terbesar
ps aux --sort=-%mem | head -20
# Cek per cgroup
for cg in /sys/fs/cgroup/memory/user/*/; do
if [ -f "$cg/memory.usage_in_bytes" ]; then
usage=$(cat "$cg/memory.usage_in_bytes" 2>/dev/null)
limit=$(cat "$cg/memory.limit_in_bytes" 2>/dev/null)
uid=$(basename "$cg" | grep -o '[0-9]*')
echo "UID: $uid | Usage: $((usage/1024/1024))MB | Limit: $((limit/1024/1024))MB"
fi
done | sort -t: -k3 -rn | head -10
Output-nya kira-kira begini:
UID: 3002 | Usage: 987MB | Limit: 1024MB # ← hampir mentok!
UID: 3005 | Usage: 234MB | Limit: 1024MB
UID: 3010 | Usage: 112MB | Limit: 512MB
UID: 3001 | Usage: 89MB | Limit: 1024MB
Dari sini kamu langsung tahu siapa yang bermasalah.
Solusi 5: Monitor dengan Script Otomatis
Supaya tidak terjebak lagi, buat script monitoring sederhana yang jalan setiap menit:
#!/bin/bash
# /usr/local/bin/memcg-monitor.sh
LOG="/var/log/memcg-alerts.log"
THRESHOLD=90 # Alert jika usage > 90% dari limit
for cg in /sys/fs/cgroup/memory/user/*/; do
if [ -f "$cg/memory.usage_in_bytes" ]; then
usage=$(cat "$cg/memory.usage_in_bytes" 2>/dev/null)
limit=$(cat "$cg/memory.limit_in_bytes" 2>/dev/null)
uid=$(basename "$cg" | grep -o '[0-9]*')
if [ "$limit" -gt 0 ] && [ "$limit" -lt 9007199254740991 ]; then
percent=$((usage * 100 / limit))
if [ "$percent" -gt "$THRESHOLD" ]; then
echo "$(date '+%Y-%m-%d %H:%M:%S') WARNING: UID $uid at ${percent}% memory usage ($((usage/1024/1024))MB/$((limit/1024/1024))MB)" >> "$LOG"
# Kirim alert via email (opsional)
# echo "UID $uid memory usage ${percent}%" | mail -s "Memory Alert" admin@server.com
fi
fi
fi
done
Tambahkan ke crontab:
# Jalankan setiap menit
* * * * * /usr/local/bin/memcg-monitor.sh
Troubleshooting Table
| Gejala | Kemungkinan Penyebab | Solusi |
|---|---|---|
| lsphp killed berulang kali dalam hitungan detik | Cgroup limit terlalu kecil | Tingkatkan memcg limit via LVE Manager |
| Hanya user tertentu yang kena OOM | User tersebut pakai script PHP boros memori | Cek aplikasi user, audit plugin/theme | Semua user kena OOM | RAM server fisik kurang atau cgroup default terlalu kecil | Upgrade RAM atau naikkan default limit |
| OOM muncul saat traffic tinggi | Too many PHP workers concurrent | Batasi max children PHP worker |
| OOM muncul tiba-tiba tanpa traffic spike | Memory leak di aplikasi PHP | Audit kode PHP, cek memory_get_usage() |
| Virtual memory tinggi tapi anon-rss rendah | Banyak file mapping, bukan heap issue | Cek file cache config, kurangi mmap usage |
Pro Tips dari NOC Engineer
Tip 1: Jangan hanya lihat RAM server secara keseluruhan. Server bisa punya 64GB RAM, tapi kalau memory cgroup per user cuma 256MB, user tetap akan kena OOM. Banyak admin yang cek free -h, lihat masih banyak sisa RAM, lalu bingung kenapa lsphp dibunuh.
Tip 2: Perhatikan pola waktu. Kalau OOM terjadi di jam-jam tertentu saja (misal malam hari atau jam 11 siang), itu biasanya berkaitan dengan traffic pattern atau cron job yang jalan.
Tip 3: Untuk CloudLinux, gunakan lvestats untuk melihat historical data.
# Lihat statistik LVE user dalam 24 jam terakhir
lvestats --lve-id=3002 --period=24h
# Lihat resource limit vs actual usage
lvestats --lve-id=3002 --detail
Tip 4: Kalau kamu pakai LiteSpeed, set memory_soft_limit lebih rendah dari memory_hard_limit — supaya ada headroom sebelum hard limit tercapai. Jangan set keduanya sama persis.
Tip 5: Pertimbangkan untuk menggunakan CloudLinux Adaptive Resource Limits. Fitur ini otomatis menyesuaikan limit berdasarkan beban server secara real-time, jadi lebih fleksibel dibanding limit statis.
Kapan Harus Naikkan RAM vs Naikkan Cgroup Limit?
Ini pertanyaan yang sering muncul. Jawabannya simpel:
- Naikkan cgroup limit kalau server masih punya banyak RAM tersisa tapi user tertentu masih kena OOM. Ini berarti RAM fisik cukup, tapi batas per user yang terlalu ketat.
- Tambah RAM server kalau
free -hmenunjukkan swap sudah terpakai signifikan dan available memory sudah rendah. Ini berarti RAM fisik memang kurang untuk semua user.
Cek dulu sebelum beli RAM:
# Cek penggunaan RAM secara keseluruhan
free -h
# Cek swap usage
swapon --show
# Cek total memory usage semua cgroup
cat /sys/fs/cgroup/memory/memory.usage_in_bytes | awk '{print $1/1024/1024/1024 " GB used"}'
FAQ
Q: Apakah Memory Cgroup Out of Memory sama dengan OOM Killer biasa?
Tidak. OOM Killer biasa (system-wide) terjadi ketika seluruh RAM server habis. Memory Cgroup OOM terjadi ketika batas memori untuk sekumpulan proses tertentu (cgroup) terlampaui — bahkan kalau server masih punya banyak RAM tersisa. Di log, OOM biasa tertulis Out of memory: Kill process, sedangkan cgroup OOM tertulis Memory cgroup out of memory. Ini penting karena solusinya beda — cgroup OOM tidak solved dengan tambah RAM server.
Q: Kenapa proses lsphp yang dibunuh, bukan proses lain?
LiteSpeed PHP (lsphp) adalah salah satu consumer memori terbesar di server shared hosting. Setiap request PHP men-spawn worker baru yang butuh memori. Kalau banyak request datang bersamaan, total konsumsi memori lsphp naik drastis. Kernel memilih lsphp sebagai kandidat OOM kill karena memang sedang menggunakan banyak memori — tapi ini juga berarti request PHP yang sedang diproses akan terganggu dan user dapat error.
Q: Bagaimana cara mencegah OOM tanpa menambah RAM atau naikkan limit?
Ada beberapa strategi: (1) Turunkan memory_limit di PHP supaya setiap worker tidak makan terlalu banyak memori. (2) Batasi jumlah max children worker PHP. (3) Optimasi aplikasi PHP — gunakan caching seperti Redis/Memcached supaya tidak query database berulang. (4) Gunakan PHP OPcache untuk cache bytecode. (5) Audit plugin WordPress yang boros memori. Strategi ini paling efektif kalau OOM terjadi karena aplikasi yang tidak dioptimasi.
Q: Apakah aman menonaktifkan OOM cgroup killer?
Tidak disarankan. Jika kamu set memory.oom_control ke 1 (disable OOM), proses yang melampaui batas tidak akan dibunuh — tapi ini bisa menyebabkan kernel hang atau sistem menjadi tidak responsif karena kehabisan memori. Lebih baik atur limit dengan benar daripada nonaktifkan proteksinya.
Related Issues
- Cara Cek dan Atasi RAM Server yang Habis
- Mengatasi LiteSpeed CPU Usage Tinggi
- Panduan CloudLinux LVE Manager untuk NOC Engineer
- WordPress Memory Usage Tinggi — Debug & Optimasi
Masalah memory cgroup ini sebenarnya sangat umum di server shared hosting, tapi banyak yang salah penanganannya karena fokus ke RAM server alih-alih memahami cara kerja cgroup. Kalau kamu sudah paham log-nya dan tahu cara baca field-field di dalamnya, troubleshooting jadi jauh lebih mudah.
Ingat — log tidak pernah bohong. Kamu cuma perlu tahu cara membacanya.