Linux Memory Management
debt(d7/e5/b7/t7)
Closest to 'only careful code review or runtime testing' (d7). The detection_hints list tools like datadog, prometheus-node-exporter, free, and vmstat — these are monitoring/observability tools that require deliberate setup and interpretation, not automated linters or compilers. OOM kills and swap pressure are only visible through active monitoring or when users start hitting 500 errors in production. The code_pattern hints confirm the issue is only surfaced at runtime: PHP-FPM workers being OOM-killed, heavy swap usage, and miscalculated pm.max_children.
Closest to 'touches multiple files / significant refactor in one component' (e5). The quick_fix mentions configuring vm.swappiness=10, monitoring /proc/meminfo MemAvailable, and recalculating pm.max_children — this spans OS-level tuning, PHP-FPM pool configuration, and PHP ini settings (memory_limit). The common_mistakes list four distinct failure modes (pm.max_children, swap config, memory_limit, RSS monitoring) each requiring separate changes across infrastructure and application config, pushing beyond a simple one-line patch.
Closest to 'strong gravitational pull' (b7). The term applies_to both web and cli contexts with tags spanning linux, php, performance, and devops. Misconfiguration of pm.max_children and memory_limit shapes every deployment decision — scaling workers, adding features that increase memory footprint, deployments under load, and infrastructure provisioning all flow through these constraints. Every future change to the PHP application must account for per-worker RSS growth, making this a persistent architectural concern.
Closest to 'serious trap' (t7). The canonical misconception is explicitly stated: 'Free memory is wasted memory' — developers see high memory usage and panic, misinterpreting healthy page cache utilisation as a problem. This directly contradicts intuition from Windows/desktop environments where high RAM usage signals trouble. A competent developer unfamiliar with Linux memory semantics will routinely misread free/top output, potentially 'fixing' a non-problem or ignoring real swap pressure, which is a serious behavioural contradiction versus common mental models.
Also Known As
TL;DR
Explanation
Linux uses virtual memory — each process sees its own address space. The page cache uses free RAM to cache disk reads (cat /proc/meminfo shows Cached). Swap extends RAM to disk — much slower, causes performance degradation. OOM (Out of Memory) killer: when RAM + swap is exhausted, the kernel kills processes to free memory — typically the largest consumer. PHP memory: each PHP-FPM worker uses 20-100MB depending on app; pm.max_children * typical_worker_memory must not exceed available RAM. Memory pressure indicators: free -h, vmstat, /proc/meminfo. PHP memory limit: memory_limit in php.ini controls per-request limit.
Common Misconception
Why It Matters
Common Mistakes
- pm.max_children calculated without accounting for page cache — leave 20% RAM for cache.
- No swap configured — without swap, OOM killer fires immediately when RAM is exhausted.
- memory_limit = -1 (unlimited) in PHP — uncontrolled memory leaks exhaust server RAM.
- Not monitoring RSS (resident set size) per PHP worker — workers grow over time with memory leaks.
Code Examples
; php-fpm.conf — too many workers for available RAM:
pm = static
pm.max_children = 100 ; 100 * 50MB = 5GB needed
; Server has 4GB RAM
; At full load: OOM killer fires, workers killed mid-request
; 500 errors, partial database writes, data corruption
; Calculate safely:
; Available RAM: 4GB - 500MB OS - 500MB MySQL = 3GB for PHP
; Average worker memory: 50MB
; Max children: 3000MB / 50MB = 60 workers
; Leave headroom: use 48
pm = dynamic
pm.max_children = 48
pm.start_servers = 10
pm.min_spare_servers = 5
pm.max_spare_servers = 15
# Monitor OOM kills:
dmesg | grep -i oom
grep -i oom /var/log/syslog