Linux memory management confuses many administrators because Linux intentionally uses nearly all available RAM. This is by design and is actually a performance optimization. This guide explains how Linux manages memory and how to correctly interpret memory statistics.
Reading the free Command
free -h
# total used free shared buff/cache available
# Mem: 7.8Gi 2.1Gi 1.2Gi 128Mi 4.5Gi 5.3Gi
# Swap: 2.0Gi 0B 2.0Gi
What Each Column Means
- total — Total physical RAM installed
- used — RAM used by applications (excluding buffers/cache)
- free — RAM that is completely unused (this will often be low — that is normal)
- shared — RAM used by tmpfs and shared memory segments
- buff/cache — RAM used for disk buffers and file caching
- available — RAM available for new applications (free + reclaimable cache). This is the number that matters.
Why Free Memory Is Low (And Why That Is Good)
Linux uses unused RAM as disk cache. When you read a file, Linux keeps it in RAM so the next read is instant. This is called the page cache. When an application needs more RAM, Linux automatically reclaims cache pages.
# Demonstrate the page cache:
# 1. Check current memory
free -h
# 2. Read a large file
dd if=/dev/zero of=/tmp/testfile bs=1M count=500
# 3. Check memory again — buff/cache increased
free -h
# 4. The "available" column is what matters
# It shows how much RAM is truly available for applications
Understanding /proc/meminfo
# Detailed memory breakdown
cat /proc/meminfo
# Key fields explained:
# MemTotal: Total usable RAM
# MemFree: Completely unused RAM
# MemAvailable: Estimated available RAM for applications
# Buffers: Raw disk block cache
# Cached: File content cache (page cache)
# SwapTotal: Total swap space
# SwapFree: Unused swap
# Dirty: Data waiting to be written to disk
# Slab: Kernel data structure cache
# SReclaimable: Slab memory that can be reclaimed
# Committed_AS: Total memory committed to processes
Monitoring Memory with vmstat
# Real-time memory statistics (update every 2 seconds)
vmstat 2
# Output columns:
# procs ---memory--- ---swap-- -----io---- -system-- ------cpu-----
# r b swpd free buff cache si so bi bo in cs us sy id wa st
# 1 0 0 1200M 128M 4500M 0 0 12 45 156 312 5 2 92 1 0
# Key indicators:
# si/so (swap in/out): Should be 0. If consistently > 0, you need more RAM
# free: Can be low if buff/cache is high
# r (runnable processes): Should be less than number of CPUs
When to Worry About Memory
# Signs of memory pressure:
# 1. "available" in free -h is below 10% of total
# 2. Swap usage is increasing over time
# 3. OOM killer is active (check dmesg)
# 4. Applications are being killed unexpectedly
# Check for OOM events:
dmesg | grep -i "out of memory"
dmesg | grep -i "killed process"
# Check swap usage over time
vmstat 5 10 # Watch si/so columns
Per-Process Memory Usage
# Top memory consumers
ps aux --sort=-%mem | head -15
# Detailed process memory map
# VSZ = Virtual memory size (includes shared libs, mapped files)
# RSS = Resident Set Size (actual physical RAM used)
# PSS = Proportional Set Size (most accurate, accounts for shared pages)
# View PSS for a specific process
sudo cat /proc/$(pgrep -f mysql)/smaps_rollup
# Quick summary of top memory users with actual RSS
ps -eo pid,ppid,rss,vsz,comm --sort=-rss | head -15
Managing Swap
# Check swap usage
swapon --show
free -h | grep Swap
# The vm.swappiness parameter controls how aggressively Linux uses swap
# Default: 60 (moderate swapping)
# Server recommendation: 10 (swap only when necessary)
cat /proc/sys/vm/swappiness
# Change swappiness (temporary)
sudo sysctl vm.swappiness=10
# Change swappiness (permanent)
echo "vm.swappiness=10" | sudo tee -a /etc/sysctl.d/99-tuning.conf
sudo sysctl -p /etc/sysctl.d/99-tuning.conf
Clearing the Cache (When Necessary)
# Usually you should NOT clear the cache — it helps performance
# But if you need to for testing:
# Drop page cache only
sudo sync && echo 1 | sudo tee /proc/sys/vm/drop_caches
# Drop page cache, dentries, and inodes
sudo sync && echo 3 | sudo tee /proc/sys/vm/drop_caches
# Note: This is temporary. Linux will rebuild the cache immediately.
Memory Troubleshooting Checklist
- Check
free -h— look at the "available" column, not "free" - Check swap with
swapon --show— growing swap usage means RAM pressure - Check for OOM events with
dmesg | grep -i oom - Identify top consumers with
ps aux --sort=-%mem | head -15 - Watch trends with
vmstat 5— look at si/so columns - Consider adjusting vm.swappiness for server workloads