Monitoring Memory Usage on Linux

Monitoring Memory Usage on Linux

Memory pressure is one of the more commonly misdiagnosed issues on Linux, largely because the kernel’s memory management makes “used” memory look alarming when it isn’t. Reading memory usage correctly means separating real application demand from cache that the kernel is using productively but can release instantly.

The Quick Check

free -h
               total        used        free      shared  buff/cache   available
Mem:            15Gi       4.2Gi       2.1Gi       412Mi       8.9Gi        10Gi

The number to watch is available, not free. available estimates how much memory could be handed to a new application right now without triggering swap, accounting for reclaimable cache. A full breakdown of every column is covered in the dedicated free command guide.

Raw Data: /proc/meminfo

cat /proc/meminfo

This file is the source free, top, and most monitoring tools read from directly. It contains far more detail than free surfaces, including per-type breakdowns of slab memory, page tables, and dirty pages waiting to be written to disk.

Key fields worth knowing:

FieldMeaning
MemTotalTotal installed RAM
MemFreeCompletely unused memory
MemAvailableEstimate of memory available for new applications
BuffersMemory used for block I/O buffers
CachedPage cache (file data cached in RAM)
SwapTotal / SwapFreeTotal and unused swap space
DirtyMemory pages modified but not yet written to disk

Finding What’s Actually Using Memory

ps aux --sort=-%mem | head -n 11

This lists the ten processes using the most memory by RSS. For an interactive, continuously updating view:

top
# then press Shift+M to sort by memory

or

htop
# press F6, select MEM%, sort descending

RSS vs. VSZ

Process memory reporting shows two different numbers that are easy to confuse:

  • VSZ (virtual size): total virtual address space mapped by the process, including shared libraries, memory-mapped files, and reserved-but-unused space. This number can look enormous and mean very little.
  • RSS (resident set size): actual physical RAM currently occupied by the process. This is almost always the more meaningful number for judging real consumption.
ps -o pid,comm,vsz,rss --sort=-rss | head

RSS can also be misleading in one direction: shared libraries loaded by multiple processes count toward each process’s RSS individually, which can make total memory usage look higher than it actually is when summed naively across processes. Tools like smem account for proportional sharing and give a more accurate real-world total.

Recognizing Real Memory Pressure

Signs that a system is genuinely short on memory, rather than just using cache productively:

  • Low available in free -h, not just low free
  • Active swap usage, visible as nonzero and changing si/so in vmstat 1 or a growing used swap in free
  • OOM killer activity in logs:
dmesg | grep -i "out of memory"
journalctl -k | grep -i "killed process"

The OOM (out-of-memory) killer is the kernel’s last resort: when memory and swap are both exhausted and a process requests more than can be freed, the kernel terminates a process chosen by a scoring heuristic that tries to free the most memory for the least disruption. Repeated OOM kills in logs are a clear signal that the system is undersized for its workload, or that a specific process has a memory leak worth investigating.

Watching Memory Over Time

watch -n 2 free -h

or for a scriptable, loggable stream:

vmstat 2

which also shows swap in/out rates (si/so) alongside memory columns, useful for correlating memory pressure with actual swap activity rather than reading them separately.

Frequently Asked Questions

What is the best command to check memory usage on Linux?

free -h gives the fastest system-wide summary. For per-process detail, top or htop show memory usage per process interactively. For the most detailed raw data, /proc/meminfo contains every metric the kernel tracks, though most of it is only needed for deep troubleshooting rather than everyday checks.

Why does Linux appear to use almost all available memory even when idle?

Linux fills unused RAM with disk cache, since idle memory provides no benefit sitting empty. This cached memory is used in the sense that it holds data, but it is instantly reclaimable the moment an application requests memory that is not otherwise available. This behavior is normal and by design, not a memory leak or a sign of a problem.

How do I find which process is using the most memory?

Run ps aux —sort=-%mem | head -n 11 to list the top 10 memory-consuming processes, or open top or htop and sort by memory usage (press Shift+M in top). For a more detailed per-process breakdown including shared memory, smem (if installed) provides more accurate real-world usage than the RSS numbers shown by ps and top alone.

What is the difference between RSS and VSZ in process memory reporting?

VSZ (virtual set size) is the total virtual address space a process has mapped, which can be much larger than actual physical memory used since it includes memory-mapped files, shared libraries, and reserved-but-unused address space. RSS (resident set size) is the actual physical RAM currently occupied by the process. RSS is almost always the more meaningful number when judging real memory consumption.

What is OOM killer and when does it activate?

The OOM (out-of-memory) killer is a kernel mechanism that terminates a process when the system has run out of available memory and swap, and cannot free enough to satisfy a memory request. It picks a victim process based on a scoring system that weighs memory usage against other factors, aiming to kill the process that frees the most memory while causing the least disruption. OOM kills are logged in dmesg and the system journal and are a strong signal that a system is undersized for its workload or that something has a memory leak.

How can I tell if a system genuinely needs more RAM versus just having a lot of cache?

Look at the available column from free rather than free or used. Low available memory combined with active swap usage (visible in free or vmstat) and a growing OOM kill history in dmesg indicates the system genuinely needs more memory or fewer running workloads. High used memory with high buff/cache and healthy available memory is normal cache behavior, not a shortage.