📑 Daftar Isi
- What Is Memory Cgroup Out of Memory?
- Reading the Log Error Correctly
- Why Does This Actually Happen?
- 1. Memory Cgroup Limit Is Too Low
- 2. PHP Memory Limit Is Too High
- 3. Traffic Spike or Bot Attack
- 4. Memory Leak in PHP Application
- 5. PHP Worker Multiplying
- How to Check Memory Cgroup Limits
- Step-by-Step Solutions
- Fix 1: Increase Memory Cgroup Limit
- Fix 2: Lower PHP Memory Limit
- Fix 3: Limit PHP Worker Multiplying
- Fix 4: Identify Memory-Heavy Users
- Fix 5: Set Up Automated Monitoring
- Troubleshooting Table
- Pro Tips from a NOC Engineer
- When to Add RAM vs. Raise Cgroup Limits
- FAQ
- Q: Is Memory Cgroup Out of Memory the same as regular OOM Killer?
- Q: Why is lsphp specifically the process being killed?
- Q: How can I prevent OOM without adding RAM or raising limits?
- Q: Is it safe to disable the OOM cgroup killer?
- Related Issues
I once got a panicked call at 5 AM from a client whose website was completely down. Every PHP page was throwing 500 errors. I SSHed into the server immediately, pulled up the logs, and found these lines screaming in /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
My first thought wasn’t “we’re out of RAM” — it was “this is a cgroup limit issue.” And that distinction matters a LOT. Many admins see these logs, panic, and immediately order more RAM. But the real problem isn’t the total RAM on the server — it’s the memory ceiling imposed on a specific group of processes.
Think of it like this: imagine you rent a small hotel room that only fits a bed and a desk. You buy a new wardrobe, but the room itself is too small — the wardrobe doesn’t fit not because you have too much stuff, but because the room’s dimensions are the constraint. That’s exactly what’s happening with memory cgroups.
What Is Memory Cgroup Out of Memory?
Memory cgroup (or memcg) is a Linux kernel feature that limits how much RAM a specific group of processes can consume. On shared hosting servers running CloudLinux or CageFS, each user gets their own memory cgroup — so one memory-hungry user can’t bring down everyone else.
When the lsphp (LiteSpeed PHP) process exceeds its assigned memory cgroup limit, the kernel kills it immediately — and that’s what those log lines represent. The process is forcefully terminated, not crashed on its own.
Reading the Log Error Correctly
This is where most people drop the ball. Every field in that log tells part of the story. Let’s break it down line by line:
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
Field-by-field breakdown:
| Field | Value | Meaning |
|---|---|---|
Memory cgroup out of memory |
— | This is cgroup-based OOM, not system-wide OOM |
Killed process 4109148 |
PID | Process ID that the kernel terminated |
(lsphp) |
Process name | LiteSpeed PHP worker — serves PHP requests |
total-vm:714676kB |
~698 MB | Total virtual memory allocated to the process |
anon-rss:98908kB |
~96 MB | Anonymous memory (heap) actually in use — most important field |
file-rss:19900kB |
~19 MB | Memory used for file mappings (file cache) |
shmem-rss:4kB |
~4 KB | Shared memory — nearly zero here |
UID:3002 |
User ID | Hosting user whose PHP process was killed |
pgtables:828kB |
Page tables | Memory for page table mappings |
oom_score_adj:0 |
0 | Default score — no kill preference applied |
The most critical takeaway from this log: the killed process is lsphp. That means a LiteSpeed PHP worker was actively serving a request when the kernel killed it mid-flight. The result? Clients see 500 errors or connection resets.
Why Does This Actually Happen?
There are several possible root causes, and you need to eliminate them one by one:
1. Memory Cgroup Limit Is Too Low
Most common cause. On CloudLinux, the default memory limit per user can be very low — sometimes just 256MB or 512MB. If a website runs WordPress with heavy plugins (WooCommerce, page builders, caching plugins), that limit gets blown through easily.
2. PHP Memory Limit Is Too High
Ironically, if you set memory_limit in PHP too high (say 512MB or 1024MB) but the memory cgroup limit is only 512MB, you’ve created a ticking time bomb. PHP is allowed to request up to 512MB, but the cgroup only allows 512MB total for ALL processes belonging to that user.
3. Traffic Spike or Bot Attack
The logs show 4 lsphp processes killed within 4 seconds (05:49:06 to 05:49:10). This is a classic pattern: many PHP workers active simultaneously, each consuming memory, and the cgroup limit gets hit.
4. Memory Leak in PHP Application
Sometimes a plugin or custom script leaks memory — each request slightly increases memory usage without ever releasing it back.
5. PHP Worker Multiplying
LiteSpeed PHP workers can spawn many child processes. If max children is set too high, total memory consumption across all workers exceeds the cgroup limit.
How to Check Memory Cgroup Limits
Before jumping to solutions, you need to know what limits are currently in place:
# Check memory limit for a specific user
cat /sys/fs/cgroup/memory/user/3002/memory.limit_in_bytes
# Check current memory usage
cat /sys/fs/cgroup/memory/user/3002/memory.usage_in_bytes
# Check via CloudLinux (different path)
cat /proc/user/3002/resource_limits 2>/dev/null || cat /sys/fs/cgroup/memory/user.slice/user-3002.slice/memory.limit_in_bytes
Or if you’re using CloudLinux with LVE Manager:
# Check limits via lvesectl
lvesectl limits --lve-id=3002
# Or via cPanel stats
cat /var/cpanel/databases.db | grep -i memory
If you see limits of 256MB or 512MB, that’s clearly why lsphp is being killed — the limit is too small for that website’s workload.
Step-by-Step Solutions
Fix 1: Increase Memory Cgroup Limit
The most direct fix. If a user needs more RAM, raise their limit.
For CloudLinux LVE:
# Raise memory limit for a specific user (in MB)
lvesectl set --lve-id=3002 --mem=2048
# Or via WHM > CloudLinux LVE Manager > Users
# Find the user, edit memory limit, save
For LiteSpeed Enterprise:
# Edit LiteSpeed config
cd /usr/local/lsws/conf/
nano httpd.conf
# Find the vhost or pool section, set memory limit
# Example for virtual host:
vhTemplate lsphp {
memHardLimit 2048M
memSoftLimit 1536M
}
# Restart LiteSpeed
systemctl restart lsws
⚠️ Warning: Don’t raise the limit too aggressively at once. Increase gradually — 512MB → 1024MB → 2048MB — and monitor for 24-48 hours before raising again.
Fix 2: Lower PHP Memory Limit
If the memory cgroup limit can’t be raised (e.g., the server is already packed), you need to lower memory_limit in PHP to prevent the conflict.
# Check current memory_limit
php -i | grep memory_limit
# Or per user
cat /home/user/.php/php.ini | grep memory_limit
# Edit php.ini (global or per user)
nano /opt/lsws/lsphp81/etc/php.ini
# Set a realistic memory_limit
memory_limit = 256M
# Restart LiteSpeed
systemctl restart lsws
Rule of thumb: PHP memory_limit should not exceed 60-70% of the memory cgroup limit. If cgroup limit is 1024MB, set PHP memory_limit to 512-768MB max.
Fix 3: Limit PHP Worker Multiplying
LiteSpeed PHP workers have settings to limit child process spawning. If unrestricted, a single user can spawn dozens of workers each consuming significant RAM.
# Check how many workers are active
ps aux | grep lsphp | grep -c ""
# Limit max children in LiteSpeed config
# Edit httpd.conf
cd /usr/local/lsws/conf/
nano httpd.conf
# Add these settings in virtual host:
vhTemplate lsphp {
maxConns 35
env PHP_LSAPI_CHILDREN 35
memSoftLimit 1024M
memHardLimit 1280M
}
# Restart
systemctl restart lsws
Fix 4: Identify Memory-Heavy Users
If this is a shared hosting server, you need to find who’s consuming the most memory:
# Show processes using the most memory, sorted by usage
ps aux --sort=-%mem | head -20
# Check 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 will look something like this:
UID: 3002 | Usage: 987MB | Limit: 1024MB # ← nearly maxed out!
UID: 3005 | Usage: 234MB | Limit: 1024MB
UID: 3010 | Usage: 112MB | Limit: 512MB
UID: 3001 | Usage: 89MB | Limit: 1024MB
From this, you can immediately see who the offender is.
Fix 5: Set Up Automated Monitoring
To prevent getting caught off-guard again, create a simple monitoring script that runs every minute:
#!/bin/bash
# /usr/local/bin/memcg-monitor.sh
LOG="/var/log/memcg-alerts.log"
THRESHOLD=90 # Alert if usage > 90% of 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"
fi
fi
fi
done
Add to crontab:
# Run every minute
* * * * * /usr/local/bin/memcg-monitor.sh
Troubleshooting Table
| Symptom | Possible Cause | Fix |
|---|---|---|
| lsphp killed repeatedly within seconds | Cgroup limit too low | Raise memcg limit via LVE Manager |
| Only specific user hit by OOM | That user’s PHP app is memory-hungry | Audit their application, plugins, and themes |
| All users getting OOM | Insufficient physical RAM or default cgroup limits too low | Upgrade RAM or raise default limits |
| OOM only during high traffic | Too many concurrent PHP workers | Limit max PHP worker children |
| OOM appears suddenly without traffic spike | Memory leak in PHP application | Audit PHP code, check memory_get_usage() |
| High virtual memory but low anon-rss | Heavy file mapping, not heap issue | Check file cache config, reduce mmap usage |
Pro Tips from a NOC Engineer
Tip 1: Don’t just look at server-wide RAM. A server can have 64GB of RAM, but if the memory cgroup per user is only 256MB, users will still hit OOM. Many admins run free -h, see plenty of RAM available, and then wonder why lsphp is being killed.
Tip 2: Pay attention to timing patterns. If OOM only happens at certain times (late night or around noon), it usually correlates with traffic patterns or scheduled cron jobs.
Tip 3: If you run CloudLinux, use lvestats for historical data.
# View LVE stats for the last 24 hours
lvestats --lve-id=3002 --period=24h
# View resource limits vs actual usage
lvestats --lve-id=3002 --detail
Tip 4: If you use LiteSpeed, set memory_soft_limit lower than memory_hard_limit — so there’s headroom before the hard limit is reached. Don’t set both to the same value.
Tip 5: Consider CloudLinux Adaptive Resource Limits. This feature automatically adjusts limits based on real-time server load, making it more flexible than static limits.
When to Add RAM vs. Raise Cgroup Limits
This is the question that comes up most often. The answer is straightforward:
- Raise cgroup limits if the server still has plenty of free RAM but a specific user is still hitting OOM. This means physical RAM is sufficient, but per-user limits are too tight.
- Add RAM to the server if
free -hshows significant swap usage and available memory is low. This means physical RAM is genuinely insufficient for all users.
Check before buying RAM:
# Check overall RAM usage
free -h
# Check swap usage
swapon --show
# Check total memory usage across all cgroups
cat /sys/fs/cgroup/memory/memory.usage_in_bytes | awk '{print $1/1024/1024/1024 " GB used"}'
FAQ
Q: Is Memory Cgroup Out of Memory the same as regular OOM Killer?
No. Regular (system-wide) OOM Killer triggers when the entire server’s RAM is exhausted. Memory Cgroup OOM triggers when the memory ceiling for a specific group of processes (cgroup) is exceeded — even if the server still has plenty of free RAM. In logs, regular OOM shows as Out of memory: Kill process, while cgroup OOM shows as Memory cgroup out of memory. This distinction matters because the solutions differ — cgroup OOM won’t be fixed by adding more RAM to the server.
Q: Why is lsphp specifically the process being killed?
LiteSpeed PHP (lsphp) is typically one of the largest memory consumers on a shared hosting server. Each PHP request spawns a worker that needs memory. When many requests arrive simultaneously, total lsphp memory consumption spikes. The kernel selects lsphp as the OOM kill candidate precisely because it’s using the most memory — but this also means active PHP requests get disrupted and users see errors.
Q: How can I prevent OOM without adding RAM or raising limits?
Several strategies: (1) Lower PHP memory_limit so each worker doesn’t consume too much. (2) Limit max PHP worker children. (3) Optimize your PHP application — use caching like Redis/Memcached to avoid repeated database queries. (4) Enable PHP OPcache for bytecode caching. (5) Audit memory-hungry WordPress plugins. These strategies are most effective when OOM is caused by unoptimized applications rather than genuine resource shortages.
Q: Is it safe to disable the OOM cgroup killer?
Not recommended. If you set memory.oom_control to 1 (disable OOM), processes exceeding their limit won’t be killed — but this can cause the kernel to hang or the system to become unresponsive due to memory exhaustion. It’s better to configure proper limits than to disable the safety mechanism.
Related Issues
- How to Check and Fix Server RAM Issues
- Fixing High CPU Usage in LiteSpeed
- CloudLinux LVE Manager Guide for NOC Engineers
- WordPress High Memory Usage — Debug & Optimization
This memory cgroup issue is extremely common on shared hosting servers, yet many admins handle it wrong because they focus on total server RAM instead of understanding how cgroups work. Once you can read these logs and understand what each field means, troubleshooting becomes significantly easier.
Remember — logs never lie. You just need to know how to read them.