Short answer: to check memory usage in Linux, run free -h. It prints total, used, free, buff/cache and available memory, plus swap. Read the available column: that is how much RAM programs can still get without swapping. A small “free” figure is normal, because Linux lends idle RAM to the disk cache and hands it back on demand.
free -h # the overview: read "available"
ps aux --sort=-%mem | head # the processes using the most RAM
vmstat 1 5 # five one-second samples: is it swapping right now?
swapon --show # is there any swap at all?
grep -E 'MemTotal|MemAvailable|SwapFree' /proc/meminfo # the raw numbersThe commands and output layouts on this page were checked on Debian 12 (kernel 6.1, procps-ng 4.0.2, util-linux 2.38.1) in a KVM guest on 21 October 2026; the numbers in the example outputs are illustrative. The smem, dmidecode and out-of-memory parts follow their documentation and the kernel’s log format and were not run there. Ubuntu, Rocky Linux and AlmaLinux ship the same tools.
Cheat sheet: memory commands by question
| Question | Command |
|---|---|
| How much RAM is there, and how much is left? | free -h |
| Show buffers and cache separately | free -h -w |
| Refresh every 2 seconds | free -h -s 2 |
| Every counter the kernel keeps | cat /proc/meminfo |
| Is the server swapping right now? | vmstat 1 |
| Which processes use the most RAM? | ps aux --sort=-%mem | head |
| Live view sorted by memory | top -o %MEM |
| Memory of one process | grep -E 'VmRSS|VmHWM|VmSwap' /proc/PID/status |
| Fair share per process (PSS) | sudo smem -r -s pss -k |
| Swap devices and their use | swapon --show |
| Did the kernel kill something for memory? | sudo journalctl -k | grep -i oom |
| How much RAM is installed? | lsmem |
How do I read free -h?
total used free shared buff/cache available
Mem: 3.8Gi 1.1Gi 412Mi 21Mi 2.5Gi 2.7Gi
Swap: 2.0Gi 0B 2.0Gi- total: the RAM the kernel manages (
MemTotal), slightly less than the RAM in the machine or the plan. More on that below. - used: memory that is in use and cannot simply be handed out. Since procps-ng 4.0.1 (Debian 12, Ubuntu 24.04) it is calculated as total minus available; older versions such as Ubuntu 22.04’s procps 3.3 subtract free, buffers and cache instead, so the same machine shows a slightly different “used” on the two.
- free: RAM nobody uses for anything, not even cache. On a server that has been up for a while this is small, and that is good: unused RAM does no work.
- shared: mostly
tmpfs, such as/dev/shmand/run. - buff/cache: kernel buffers, the page cache (recently read files) and reclaimable kernel slab. Most of it is given back the moment a program asks for memory.
free -h -wshows buffers and cache as two columns. - available: the kernel’s estimate (
MemAvailable) of how much memory a new program can get without pushing anything to swap. This is the number to watch.
With the new calculation, free, used and buff/cache no longer add up to total. That is expected: available counts only the part of the cache the kernel can really reclaim, and used is derived from it. Units are binary: Gi is a gibibyte (1,024 MiB). free -m prints mebibytes without suffixes, which is handier in scripts, and --si switches to powers of 1,000.
Why is free memory so low?
Because Linux uses otherwise idle RAM as a file cache. Read a 2 GB log once and it stays in RAM until something needs the space, so reading it again is fast. The cache shrinks automatically under pressure, which is why a server with 400 MB “free” and 2.7 GB “available” is healthy. Dropping the cache by hand (as root, echo 3 > /proc/sys/vm/drop_caches) only makes the next reads slower; it is a benchmarking tool, not a fix.
What does /proc/meminfo show?
free, top and htop all read /proc/meminfo. Reading it directly gives you the counters they summarise, in kibibytes:
grep -E '^(MemTotal|MemFree|MemAvailable|Buffers|Cached|SwapTotal|SwapFree|Shmem|SReclaimable|AnonPages|Committed_AS|Dirty):' /proc/meminfo| Field | What it means |
|---|---|
MemTotal | Usable RAM the kernel manages |
MemFree | Completely unused RAM (free's "free") |
MemAvailable | Estimate of RAM available for new programs without swapping |
Buffers | Kernel buffers for block devices |
Cached | Page cache, including tmpfs and shared memory |
SReclaimable | Kernel slab memory that can be freed (free adds it to cache) |
AnonPages | Memory of programs that is not backed by a file: heaps, stacks |
Shmem | tmpfs and shared memory segments |
SwapTotal / SwapFree | Swap size and the part not in use |
Committed_AS | Memory all processes have asked for, used or not yet |
Dirty | Changed file data not yet written to disk |
Committed_AS above MemTotal plus swap is not an error on its own: Linux overcommits by default, because programs reserve more than they ever touch. It becomes interesting when available is low at the same time.
Is the server swapping right now? vmstat 1
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 51200 421904 60212 2554180 0 0 3 18 210 395 4 1 95 0 0
2 0 51200 420112 60212 2554200 0 0 0 44 480 820 6 2 92 0 0
1 0 51200 419876 60220 2554204 0 0 0 12 455 790 5 1 94 0 0The first line is an average since boot; the following lines are the live samples. Memory columns are in KiB (-S M switches to MiB). swpd is swap in use, and si and so are the memory swapped in and out per second. A few megabytes in swap with si and so at zero is harmless: idle pages were moved out once. Non-zero si and so in sample after sample means the server is short of RAM right now, and a high wa (waiting for I/O) usually comes with it. vmstat -s -S M prints a one-off list of the same totals.
For a measure that does not depend on swap at all, read the kernel’s pressure stall information. cat /proc/pressure/memory prints how much of the last 10, 60 and 300 seconds tasks spent waiting for memory; anything above zero in the avg10 field during normal operation is worth a look.
How do I sort processes by memory in top and htop?
- top: press
Shift+Mwhile it runs, or start it withtop -o %MEM. The two memory lines in the header areMiB Mem(total, free, used, buff/cache) andMiB Swap, which ends withavail Mem, the same estimate as free’s available. - htop: press
M, or start it withhtop -s PERCENT_MEM. The memory bar colours separate used memory from buffers and cache; htop explained decodes them and theRES,SHRandVIRTcolumns.
Which process is using the memory?
ps aux --sort=-%mem | head # BSD-style list, biggest first
ps -eo pid,user,rss,comm --sort=-rss | head # only the columns you need (RSS in KiB)
ps -C php-fpm8.2 -o rss= | awk '{s+=$1} END {print s/1024 " MiB"}' # all workers of one programIn ps aux, %MEM is RSS as a share of physical RAM, RSS is the resident set in KiB and VSZ the virtual size. The ps aux guide covers every column. For a single process, its status file holds the peak as well as the current value:
grep -E 'VmRSS|VmHWM|RssAnon|RssFile|VmSwap' /proc/1234/status
# VmRSS: 184320 kB resident now
# VmHWM: 412516 kB highest resident value since the process started
# RssAnon: 151200 kB heap and stack
# RssFile: 33120 kB mapped files such as libraries
# VmSwap: 0 kB this process's pages in swapVmHWM is the high-water mark: a worker that sits at 180 MB but peaked at 400 MB needs the 400 MB when you size the server or set pm.max_children in PHP-FPM.
RSS, PSS, USS and VSZ: which number is real?
| Measure | What it counts | Use it for |
|---|---|---|
| VSZ (VIRT) | All address space the process has mapped, used or not | Almost nothing; it is routinely far above RAM |
| RSS (RES) | Pages of the process in RAM, shared libraries counted in full | A quick ranking; sums over-count |
| PSS | RSS with each shared page divided by the number of processes sharing it | Adding up a group of processes honestly |
| USS | Pages only this process uses | What you would get back by killing it |
RSS counts shared pages in every process that maps them, so adding up the RSS of 20 PHP or Postgres workers can exceed the RAM in the machine. PSS splits each shared page between its users. The kernel publishes it per process in /proc/PID/smaps_rollup: for a short-lived head process in the test, it listed Rss: 1684 kB but Pss: 218 kB, because almost all of it was the shared C library. smem reads those files for every process:
sudo smem -r -s pss -k | head -15 # processes by PSS, biggest first
sudo smem -u -k # totals per user
sudo smem -w -k # kernel, cache and processes for the whole systemHow do I check swap usage?
swapon --show # no output: no swap configured
free -h # the Swap: line
grep -s VmSwap /proc/[0-9]*/status | sort -k2 -n | tail # which processes sit in swapMany VPS images ship without swap, and then the Swap line reads 0B across the board. A small swap file gives the kernel somewhere to put idle pages instead of killing a process when memory runs out for a moment; adding swap space on Linux shows how to create one and how to set vm.swappiness. Swap is a cushion, not extra RAM: a server that swaps all day is too small for its job.
Signs that the server ran out of memory
- A process dies with just
Killedon the terminal, or a container exits with code137. - The kernel log has a line like
Out of memory: Killed process 2314 (mysqld) total-vm:… anon-rss:…. systemctl statusof a service showsResult: oom-kill.- The server becomes sluggish, load climbs, and
kswapd0shows up near the top oftop.
sudo dmesg -T | grep -i -E 'out of memory|killed process'
sudo journalctl -k -b -1 | grep -i oom # the previous boot, after a crash or rebootThe process named in that line is the one the kernel chose to kill, not necessarily the one that ate the memory. The out-of-memory killer guide walks through confirming the cause and keeping it from happening again. Memory pressure also shows up as CPU load, because reclaiming pages and swapping cost CPU time and I/O waits; if you came here from a busy CPU graph, check VPS high CPU usage as well.
Why does my VPS show less RAM than the plan?
MemTotal is the memory the kernel manages after it has set aside what it needs at boot: its own code, firmware reservations and the table that describes every page of RAM (64 bytes per 4 KiB page on x86-64, about 1.6 %). In the Debian 12 KVM guest used for this page, lsmem reported Total online memory: 40G while free -h showed a total of 39Gi, so about 850 MiB never appeared in MemTotal. On a 4 GB plan, expect a total of roughly 3.8Gi.
lsmem | tail -3 # memory the system has online, in blocks
grep MemTotal /proc/meminfo # what the kernel can hand out
sudo dmidecode -t memory | grep -E 'Size|Type:|Speed' # bare metal: the modules in the slotsTwo more reasons for a gap: GB versus GiB (a “4 GB” figure in powers of 1,000 is only 3.7 GiB), and on bare metal, memory used by integrated graphics or firmware. Inside a virtual machine, dmidecode describes the hypervisor’s virtual hardware rather than real modules; the ECC memory guide explains what it can and cannot tell you there. If the total is far below what you pay for, not a few percent, ask the provider.
How do I know the server needs more RAM?
Look at the trend, not one snapshot. A server that keeps a healthy share of its RAM available at peak time, swaps nothing in vmstat and has no OOM lines in the kernel log has enough. Act when available falls close to zero at busy hours, si/so stay non-zero, or the OOM killer appears. First check whether one process grows without limit (a leak shows as an RSS that only ever rises) and whether caches such as a database buffer pool or pm.max_children are set larger than the machine. Capping a service with MemoryMax= in its systemd unit keeps one program from taking the rest of the server down with it.
Frequently asked
What is the difference between free and available memory in Linux?
free is RAM that nothing uses at all, not even the file cache. available is the kernel's estimate (MemAvailable in /proc/meminfo) of how much memory new programs can get without swapping, counting the cache it can reclaim. On a healthy server free is often small and available large, so watch available.
How do I see which process uses the most memory?
Run 'ps aux --sort=-%mem | head', or 'ps -eo pid,user,rss,comm --sort=-rss | head' for just the resident memory in KiB. In top press Shift+M, in htop press M. RSS counts shared libraries in every process that uses them, so for a fair total per program use PSS from smem or /proc/PID/smaps_rollup.
Why does my VPS show less RAM than my plan?
The kernel reserves memory at boot for its own code and firmware areas, and the table that describes every page of RAM alone takes about 1.6 % of it, so free -h on a 4 GB server shows a total of about 3.8Gi. GB versus GiB adds to the gap. A difference of a few percent is normal; a large one is a question for the provider.
How do I check swap usage in Linux?
swapon --show lists swap devices and files with their size and use; no output means there is no swap. The Swap line of free -h shows total and used, and vmstat 1 shows si and so, the memory swapped in and out per second. si and so that stay above zero mean the server is short of RAM.