Troubleshooting Linux Slab Allocator Exhaustion, Kernel Dentry Cache Bloat, and Low-Memory OOM Freezes: The Complete Production Runbook

An exhaustive systems engineering runbook for diagnosing and resolving Linux kernel Slab allocator bloat, unfreeable dentry and inode caches, kswapd CPU spinning, and unexpected OOM kills on high-concurrency web and database servers.

Troubleshooting Linux Slab Allocator Exhaustion, Kernel Dentry Cache Bloat, and Low-Memory OOM Freezes: The Complete Production Runbook

On high-concurrency web servers, database clusters, and container hosts, system administrators frequently encounter an elusive memory exhaustion anomaly: total free RAM collapses to near zero, the Out-Of-Memory (OOM) killer begins terminating critical processes (such as mysqld, nginx, or php-fpm), yet standard userland process monitors like top or ps show that all active processes combined account for only a small fraction of installed physical memory[1][2].

The root cause of this discrepancy is kernel-space memory consumption managed by the Linux Slab Allocator (SLUB/SLAB)[3]. Workloads that perform millions of filesystem lookups—such as WordPress media libraries, active cPanel mail queues, continuous rsync backups, Git repositories, or high-throughput static caching layers—cause directory entries (dentries) and filesystem metadata objects (inodes) to flood kernel memory[1][4]. When the kernel’s memory reclamation subsystem fails to prune these caches fast enough, the server enters direct reclaim stalls, causing high load averages, kswapd CPU thrashing, and unprovoked OOM crashes[1].

This runbook provides the diagnostic methodology, kernel telemetry parsing, and sysctl tuning required to identify and permanently remediate Slab exhaustion in production environments.


Anatomy of the Linux Slab Allocator and /proc/meminfo

The Linux kernel allocates memory for internal data structures (such as file descriptors, process descriptors, network sockets, and filesystem metadata) using the Slab allocator rather than the standard page allocator[3]. This eliminates internal fragmentation by maintaining pre-allocated pools of contiguous objects of identical sizes[3].

To distinguish between userland memory and kernel metadata, inspect /proc/meminfo[4]:

cat /proc/meminfo | grep -E "MemTotal|MemFree|MemAvailable|Cached|Buffers|Slab|SReclaimable|SUnreclaim"

A compromised server suffering from Slab exhaustion exhibits output similar to this:

MemTotal:       65792248 kB
MemFree:          842104 kB
MemAvailable:    2104320 kB
Buffers:          112440 kB
Cached:          8450212 kB
Slab:           52485600 kB
SReclaimable:   48912400 kB
SUnreclaim:      3573200 kB

In this production capture, out of 64 GB of total RAM, 52.4 GB is consumed entirely by the kernel Slab, with 48.9 GB marked as SReclaimable[1][4].

Metric Subsystem Definition Operational Significance
Slab Total kernel memory reserved by the Slab allocator[4]. Sum of SReclaimable and SUnreclaim.
SReclaimable Slab objects that the kernel can theoretically shrink under memory pressure[1][4]. Predominantly contains directory entry caches (dentry) and filesystem inodes (inode_cache, ext4_inode_cache, xfs_inode).
SUnreclaim Slab objects that cannot be freed until explicitly destroyed by owner[4]. Includes active task structs, kernel thread stacks, network sockets, and driver buffers.

Why SReclaimable Fails to Free: The Direct Reclaim Bottleneck

A common operational misconception is that because SReclaimable is labeled “reclaimable,” it will always yield memory gracefully when an application demands it[1]. In production, this assumption breaks down under two scenarios:

  1. Inode Pinning by Open File Descriptors: If active worker threads (e.g., thousands of PHP-FPM or Nginx workers) hold open references to files or directories, the associated dentry and inode structures are marked as pinned (busy) and cannot be reclaimed by the Virtual File System (VFS) shrinker[1][3].
  2. Reclaim Latency and Lock Contention: Reclaiming a dentry requires acquiring filesystem locks (e.g., dcache_lock or RCU readers) and flushing dirty metadata back to physical storage. Under bursty allocation spikes, the kernel’s background daemon (kswapd) falls behind the allocation rate, forcing incoming memory allocations into synchronous direct reclaim (allocstall)[1]. The latency of direct reclaim frequently exceeds application timeouts, causing web requests to hang or triggering the kernel OOM killer[1].

Step 1: Profiling Kernel Slab Objects with slabtop

The standard utility for real-time inspection of Slab caches is slabtop, part of the procps-ng suite[2]. Execute slabtop sorted by total memory consumption:

slabtop -o -s c | head -n 25
 Active / Total Objects (% used)    : 14820140 / 15012400 (98.7%)
 Active / Total Slabs (% used)      : 938275 / 938275 (100.0%)
 Active / Total Caches (% used)     : 112 / 168 (66.7%)
 Active / Total Size (% used)       : 48921400K / 49501200K (98.8%)
 Minimum / Average / Maximum Object : 0.02K / 3.30K / 4096.00K

  OBJS ACTIVE  USE OBJ SIZE  SLABS OBJ/SLAB CACHE SIZE NAME                   
12540120 12498200  99%    0.19K 597148       21   2388592K dentry
 8920100  8874100  99%    1.08K 601240       15   9619840K ext4_inode_cache
 4120300  4098100  99%    0.57K 294307       14   2354456K radix_tree_node
 1240100  1210400  97%    2.06K  82673       15   1653460K kmalloc-2k
  840200   820100  97%    1.00K  52512       16    840192K kmalloc-1k

Interpreting the Diagnostics

  • dentry: Represents directory path components cached in memory[1]. Over 12 million active dentries indicate intensive filesystem traversals.
  • ext4_inode_cache / xfs_inode: Inodes store file metadata (permissions, disk blocks, modification timestamps)[1]. High inode counts paired with high dentry counts confirm VFS metadata bloat.
  • radix_tree_node: Internal kernel data structures utilized by the page cache to look up pages belonging to file mappings[3].

Step 2: Correlating Slab Growth with Filesystem Activity

To locate the specific service or process responsible for generating millions of dentries, evaluate filesystem usage patterns:

A. Quantifying Total Inodes on Mounted Partitions

df -i

A server where disk usage is only 20% but inode consumption is 95% is a prime candidate for dentry bloat, commonly caused by runaway PHP session directories (/var/cpanel/php/sessions or /var/lib/php/sessions), WordPress transients, or mail spool directories (/var/spool/exim).

B. Identifying Processes with High Open File Descriptors

lsof +L1 | awk '{print $1, $2, $3}' | sort | uniq -c | sort -rn | head -n 15

Alternatively, aggregate open file counts per process group:

for pid in $(ps -eo pid --no-headers); do
    count=$(ls -1 /proc/$pid/fd 2>/dev/null | wc -l)
    if [ "$count" -gt 1000 ]; then
        comm=$(cat /proc/$pid/comm 2>/dev/null)
        echo "PID $pid ($comm): $count file descriptors"
    fi
done | sort -k4 -rn | head -n 10

Step 3: Emergency In-Memory Cache Mitigation

When a production node is critically low on available memory and facing imminent OOM termination, execute an emergency memory reclamation pass[1]:

# 1. Flush all dirty filesystem pages to physical disk first
sync

# 2. Instruct the kernel to drop reclaimable slab objects (dentries and inodes)
echo 2 > /proc/sys/vm/drop_caches

Important: Never write 3 to drop_caches on a busy database server during peak business hours. Writing 3 flushes the entire filesystem page cache alongside slab objects, forcing all subsequent database and application reads to hit physical storage, inducing extreme I/O wait latency[1]. Writing 2 selectively targets clean dentries and inodes, recovering gigabytes of memory with minimal page-cache disruption[1].

Immediately verify memory recovery:

cat /proc/meminfo | grep -E "MemFree|MemAvailable|Slab|SReclaimable"

Step 4: Permanent Kernel Tuning via sysctl

Emergency cache drops are temporary workarounds; without sysctl tuning, dentry caches will re-accumulate within hours. The Linux kernel provides dedicated tuning knobs in /etc/sysctl.conf to govern metadata reclamation behavior[1].

A. Tuning vm.vfs_cache_pressure

The vfs_cache_pressure parameter controls the kernel’s tendency to reclaim memory used for directory and inode objects relative to page cache and swap cache[1]:

  • Default (100): The kernel reclaims dentries and inodes at a balanced rate relative to page cache and swap[1].
  • Values below 100: The kernel aggressively retains dentries and inodes. Setting this value to 0 prevents the kernel from ever freeing dentries under memory pressure, guaranteeing catastrophic OOM failures[1].
  • Values above 100 (e.g., 200 to 500): Instructs the kernel to aggressively reclaim dentry and inode caches, shrinking the Slab proactively before userland applications experience allocation stalls[1].

On file-intensive systems, configure:

# Aggressively reclaim directory and inode caches
vm.vfs_cache_pressure = 200

B. Tuning vm.min_free_kbytes for Atomic and Slab Allocations

The min_free_kbytes parameter forces the Linux VM manager to preserve a dedicated reserve pool of free physical memory[1]. This reserve ensures that atomic allocations (such as network packet processing in SoftIRQ context or high-priority slab expansions) do not fail when memory is tight[1].

On 64 GB systems, the kernel default of ~67 MB is insufficient to absorb bursty traffic spikes. Scale this parameter proportionally:

# Reserve 1024 MB of contiguous low-memory pool for kernel and network allocations
vm.min_free_kbytes = 1048576

Append these hardened directives to /etc/sysctl.d/99-slab-tuning.conf:

# Proactively reclaim dentry and inode caches
vm.vfs_cache_pressure = 200

# Prevent direct-reclaim lockups by establishing a 1GB atomic allocation reserve
vm.min_free_kbytes = 1048576

# Initiate asynchronous background dirty-page writeout early to prevent I/O stalls
vm.dirty_background_ratio = 5
vm.dirty_ratio = 10

# Minimize swapping while keeping emergency swap space available
vm.swappiness = 10

Apply the configuration immediately without a reboot:

sysctl --system

Infrastructure Sizing for Memory-Intensive Workloads

High-concurrency e-commerce portals, multi-tenant cPanel environments, and heavy database instances operating in Pakistan generate massive filesystem metadata overhead. When virtualized environments share host-level page caches or suffer from I/O noisy-neighbor throttling, kernel metadata reclamation slows dramatically, exacerbating Slab exhaustion.

Deploying on high-performance enterprise dedicated servers provides unshared, dedicated hardware memory channels and native NVMe block queues capable of sustaining millions of metadata operations per second. For organizations bound by domestic regulatory frameworks and financial sovereignty mandates, hosting on enterprise dedicated servers in Pakistan guarantees dedicated DDR5 ECC memory channels, sub-millisecond local storage access, and uninterrupted operational reliability.


Automated Health Monitoring Script

Deploy this diagnostic bash script via cron (/usr/local/bin/check_slab_health.sh) to detect and alert on anomalous Slab inflation before OOM conditions develop:

#!/usr/bin/env bash
# Production Slab Allocator and Dentry Health Check
set -euo pipefail

ALERT_THRESHOLD_PERCENT=50
LOG_FILE="/var/log/slab_monitor.log"

MEM_TOTAL=$(awk '/MemTotal:/ {print $2}' /proc/meminfo)
SLAB_TOTAL=$(awk '/Slab:/ {print $2}' /proc/meminfo)
SRECLAIMABLE=$(awk '/SReclaimable:/ {print $2}' /proc/meminfo)

SLAB_PERCENT=$(( SLAB_TOTAL * 100 / MEM_TOTAL ))

if [ "$SLAB_PERCENT" -ge "$ALERT_THRESHOLD_PERCENT" ]; then
    TIMESTAMP=$(date "+%Y-%m-%d %H:%M:%S")
    MSG="[WARNING] $TIMESTAMP: Kernel Slab usage is at ${SLAB_PERCENT}% (Total: $((SLAB_TOTAL/1024))MB, Reclaimable: $((SRECLAIMABLE/1024))MB)"
    echo "$MSG" >> "$LOG_FILE"
    
    # Capture top slab consumers for post-incident review
    echo "--- Slabtop Snapshot ---" >> "$LOG_FILE"
    slabtop -o -s c | head -n 12 >> "$LOG_FILE"
    
    # Optional emergency relief: prune clean dentries if Slab exceeds 75%
    if [ "$SLAB_PERCENT" -ge 75 ]; then
        echo "[CRITICAL] Slab exceeded 75%. Executing emergency dentry sync and drop." >> "$LOG_FILE"
        sync && echo 2 > /proc/sys/vm/drop_caches
    fi
fi

Make the script executable and schedule it every 15 minutes:

chmod 750 /usr/local/bin/check_slab_health.sh
echo "*/15 * * * * root /usr/local/bin/check_slab_health.sh >/dev/null 2>&1" > /etc/cron.d/slab_monitor

Sources & Official References
  1. The Linux Kernel Documentation — Documentation for /proc/sys/vm/*: Virtual Memory Subsystem & Kernel Parameters. Official canonical kernel documentation defining the operational mechanics of vfs_cache_pressure, drop_caches, min_free_kbytes, and memory reclaim thresholds under heavy VFS metadata loads.
  2. Linux Programmer's Manual — slabtop(1) — Display Kernel Slab Cache Information in Real Time. Official system utility man page covering slab cache metrics, object sorting criteria, and memory consumption profiling.
  3. The Linux Kernel Documentation — Short Users Guide to the SLUB Allocator. Technical specifications covering the Linux SLUB allocator architecture, slab caches, object pooling, and debug diagnostics.
  4. Linux Programmer's Manual — proc(5) — Process Information Pseudo-Filesystem (/proc/meminfo and /proc/slabinfo). Official reference detailing kernel memory telemetry, including Slab, SReclaimable, and SUnreclaim field definitions.

Bare-Metal Performance & Kernel Control

Eliminate Kernel Memory Contention with Dedicated Bare-Metal Infrastructure

High-throughput databases, WordPress clusters, and caching layers demand full physical RAM isolation without hypervisor memory balloons. Nextgen Hosting delivers unmetered bare-metal compute, enterprise NVMe storage, and dedicated DDR5 ECC memory pools in Tier-3 facilities across Pakistan and global hubs.

Deploy Dedicated Servers in Pakistan Explore Global Bare-Metal Fleet

Disclaimer: This post is for informational and educational purposes only, accurate to the best of our knowledge at publication. It does not constitute advice. We do not guarantee accuracy or completeness and accept no liability for any decisions or losses resulting from reliance on this content.