Linux · commonly confused
Free memory vs available memory
Short answer
free is memory nothing is using at all; available is the kernel's estimate of how much a new program could get without swapping, which counts the page cache it can give back. On a Linux server free can be small even when nothing is wrong, and available is the number to watch — and even available is not pressure. Pressure is the kernel having to work for memory: reclaiming, swapping in and out, tasks stalling.Measured on this site's production server, a 2 GB EC2 instance, . The figures on this page were read from that machine, not taken from documentation.
First published
On this page · 10 sections
In simple terms
Linux keeps recently read files in RAM, in the page cache, because memory holding nothing is memory wasted. So after a while much of the RAM can hold cache. The kernel takes that memory back when a program needs it, and free does not count it as used.
free counts only memory holding nothing at all. It shrinks as files are read into the page cache, so it can be small on a perfectly healthy server, and it says almost nothing about whether that server is short of memory.
available is the useful number: the kernel's estimate of what a new program could get without swapping — roughly the free memory plus the cache it could give back. When that gets low, the server really is running short.
Neither number shows pain directly. Little available memory can be fine, and swap in use can be fine. Trouble is the kernel having to work for memory: reclaiming, swapping in and out, tasks waiting.
Words used on this page
- MemFree
- Memory holding nothing at all.
freeshows it in its free column. - MemAvailable
- The kernel's estimate of how much memory a new program could get without swapping.
freeshows it in its available column. - page cache
- Copies of file data kept in RAM after a read or write, so the next read does not have to go to disk.
- buff/cache
- free's column for Buffers, Cached and SReclaimable added together. Part of it, such as tmpfs and shared memory, cannot simply be dropped.
- reclaim
- The kernel freeing pages for reuse, by dropping cache it can re-read or writing pages out to swap. When it happens in the middle of an allocation, the program waits.
- swap in, swap out
- Moving pages from disk back into RAM, and from RAM out to disk. vmstat shows them per second as si and so.
- SwapCached
- Pages that were swapped out, have been read back in, and still keep their copy in swap.
- pressure stall information
- PSI: the share of recent time in which tasks waited for memory, in /proc/pressure/memory, as averages over 10, 60 and 300 seconds.
- anon and file
- Two lines in a cgroup's memory.stat: anon is program memory with no file behind it, file is cached file data, including tmpfs and shared memory.
- OOM killer
- The kernel's last resort when memory cannot be reclaimed: it ends a process to free memory.
What actually happens
free(1) reads /proc/meminfo. Its free column is MemFree, unused memory. buff/cache is Buffers plus the page cache plus reclaimable slab. available is MemAvailable, which the manual describes as an estimate of how much memory is available for starting new applications, without swapping, taking the page cache into account and allowing that not all reclaimable slab can actually be reclaimed. MemAvailable exists since Linux 3.14.
Measured on this site's own production server, a 2 GB EC2 instance, on 8 Oct 2026: free 94 MB, buff/cache 1,481 MB, available 1,363 MB, 54 MB of swap in use, no swapping in progress, and memory pressure averages of zero. By the free column it was nearly out of memory. By every measure that matters it was healthy.
The same server during a Next.js image build showed the other side: available fell as low as 269 MB, swap in use passed 1.1 GB, and pages moved in and out of swap at tens of megabytes a second. That is memory pressure, and it shows as activity — the si and so columns of vmstat, pswpin/s and pswpout/s in sar -W — not as a small free figure.
Pressure stall information makes it explicit. /proc/pressure/memory reports the share of time in which at least some tasks (the some line) or all non-idle tasks (full) were stalled on memory, as averages over 10, 60 and 300 seconds. The amount of page cache does not appear there; time spent reclaiming memory, or reading back pages from swap or from files that were evicted while still in use, does.
Reading memory on a Linux server
free -m # read "available", not "free" grep -E 'MemFree|MemAvailable|^Cached|SReclaimable' /proc/meminfo # Is memory actually under pressure? Look at activity, not levels. vmstat 5 # si/so: swapped in/out per second cat /proc/pressure/memory # share of time tasks stalled on memory sar -W 5 3 # pswpin/s, pswpout/s (sysstat) # A service's "memory" can be mostly cache it read. grep -E '^(anon|file) ' /sys/fs/cgroup/system.slice/docker.service/memory.stat
Do not "fix" low free memory with echo 3 > /proc/sys/vm/drop_caches. The kernel documentation says those caches are reclaimed automatically when memory is needed, that dropping them can cost significant I/O and CPU to rebuild, and that it is not recommended outside testing or debugging.
Try it yourself
Before you start
- A shell on the Linux machine you want to check. Everything here reads Linux's
/procand/sysfiles, which macOS and Windows do not have. - The tools:
freeandvmstatcome from the procps package,sarfrom sysstat. Ifsaris missing,vmstat 5shows the same swap-in and swap-out activity in itssiandsocolumns. - Linux 3.14 or later for
MemAvailable, and a kernel with pressure stall information enabled for/proc/pressure/memory. When PSI is switched off, the whole/proc/pressuredirectory is missing. - No root access.
/proc/meminfoand/proc/pressure/memoryare readable by every user. Root is only needed to write kernel settings such asdrop_caches, which this page advises against. - For a single service's figures, cgroup v2 (
stat -fc %T /sys/fs/cgroup/printscgroup2fs) and the service's cgroup path, whichcat /proc/<pid>/cgroupshows on its0::line.
Reading /proc/meminfo the way free does
Not reproduced: this was written on macOS, which has neither free nor /proc. The output is the example /proc/meminfo printed in the Linux kernel documentation (The /proc Filesystem, meminfo section), cut down to the lines this grep selects. Each line is verbatim. The documentation does not say what machine the sample came from, and this machine has no swap configured.
Command
grep -E '^(MemTotal|MemFree|MemAvailable|Buffers|Cached|Shmem|SReclaimable|SwapTotal|SwapFree):' /proc/meminfo
Output · as shown in Linux kernel — The /proc Filesystem (meminfo)
MemTotal: 32858820 kB MemFree: 21001236 kB MemAvailable: 27214312 kB Buffers: 581092 kB Cached: 5587612 kB SwapTotal: 0 kB SwapFree: 0 kB Shmem: 9976 kB SReclaimable: 517708 kB
How to read it
freereads these same fields. Its free column isMemFree: 21001236 kB, about 20 GiB of the 31.3 GiB inMemTotal. Free is large on this machine. It would be much smaller on one whose page cache had grown, and that alone would say nothing about a shortage.- Its buff/cache column is
Buffers+Cached+SReclaimable: 581092 + 5587612 + 517708 = 6686412 kB, about 6.4 GiB. Note thatCachedincludesShmem, here 9976 kB of tmpfs and shared memory, which the kernel cannot simply drop. - Its available column is
MemAvailable, 27214312 kB. That is 473336 kB less than free plus buff/cache, because the kernel's estimate keeps back the page cache the system needs to run and slab it cannot reclaim. In procps 4.0.4, free's used column is total minus available: 5644508 kB here. SwapTotalandSwapFreeare both 0: there is no swap. vmstat'ssiandsowould stay at zero however short of memory this machine got, so on a server like this, pressure shows in/proc/pressure/memoryand not in swap activity.
The mistake this causes
Alerting on, or acting on, the free column — or on swap simply being in use.
Why people do it free counts only memory holding nothing; the page cache is designed to fill the rest and is given back on demand. Swap in use is history: pages moved out at some point. Some may have been read back in since and still keep a copy in swap, which /proc/meminfo counts as SwapCached. Neither one measures a shortage.
What you see Alerts that fire on healthy servers, scheduled cache drops that send cached reads back to disk, instances upsized to fix a number that was never the problem — while real pressure, which shows as swap activity and stalls, goes unwatched.
If it goes wrong
cat: /proc/pressure/memory: No such file or directory- Pressure stall information is off. The kernel creates
/proc/pressureonly when PSI is enabled. Kernels built with PSI but disabled by default turn it on with thepsi=1boot parameter. Until then, use vmstat'ssiandsocolumns. - The grep on
/sys/fs/cgroup/system.slice/docker.service/memory.statreportsNo such file or directory - Check that the machine uses cgroup v2:
stat -fc %T /sys/fs/cgroup/should printcgroup2fs. Then find the real path from the service's main process: the0::line ofcat /proc/<pid>/cgroupis its directory under/sys/fs/cgroup. free -minside a container does not match the container's memory limit- Expected. Kubernetes' documentation notes that
free -mdoes not work in a container. Read the container's cgroup instead:memory.currentfor usage,memory.maxfor its limit, andmemory.statfor the anon and file split. - Kubernetes reports low
memory.availableor evicts pods whilefreeon the node shows plenty available - They are different calculations. The kubelet computes
memory.availablefrom the cgroupfs as capacity minus the working set, and only excludes inactive file cache. Active file cache counts against it, while MemAvailable treats more cache as reclaimable. Compare against the kubelet's own calculation, which its documentation links to as a script. sar: command not foundsaris in the sysstat package. Install it, or usevmstat 5, whosesiandsocolumns show the same swap-in and swap-out activity.
How it shows up in production
A check on a small server fires: free memory 94 MB of 2 GB.
Someone logs in, sees 54 MB of swap in use as well, and concludes the box is out of memory.
available says 1,363 MB, vmstat shows no swapping, /proc/pressure/memory averages zero. The memory is cache, and the swap was written days earlier during a build and never needed back. systemd even reports docker.service at 499 MB — of which 451 MB is reclaimable file cache.
The real problem on that same server appeared only during deploys: available collapsing to a few hundred MB while swap churned. The fix went into the build, not the cache, and the alert moved from free to available and swap activity.
How to tell which one you are hitting
- Is available low, or only free?
- Low free on its own is normal once the page cache has grown. Low available is what needs attention.
- Is swap moving, or just occupied?
- Occupied with si/so near zero is history. Sustained swap-in and swap-out is pressure.
- Are tasks stalling on memory?
- Watch the avg10/avg60/avg300 values in /proc/pressure/memory over time; values above zero mean work waited for memory.
- Is a service's memory figure mostly cache?
- Compare anon and file in its cgroup's memory.stat. file is mostly page cache the kernel can reclaim, but it includes shmem (tmpfs and shared memory), which can only go to swap; subtract it to get the reclaimable part.
Security considerations
- Swap holds whatever was in memory, including secrets. The mlock(2) manual warns that passwords or keys could be paged onto swap "where they might be accessible to the enemy" after the program has erased them and exited. Programs that hold keys should lock those pages with
mlock. The manual adds that suspend saves RAM to disk regardless of memory locks. - When available really runs out and reclaim fails, the kernel's OOM killer ends a process. It chooses by memory use, not by importance, so the victim can be your database. Watch available and pressure rather than free, so you hear about it before then. For processes that must survive, lower their
/proc/<pid>/oom_score_adj; -1000 exempts a process entirely, which means something else is killed instead. - Inside a container,
freedoes not show the container's limit: Kubernetes' documentation saysfree -mdoes not work there. A program that sizes its caches from/proc/meminfocan grow past its cgroup'smemory.max, and the kernel then invokes the OOM killer inside that cgroup. - Cache drops leave a trail. Writing to
drop_cachesneeds root, and the kernel logs each use, as in the documentation's examplecat (1234): drop_caches: 3, naming the process. If disk reads spike on a schedule, look for that line before suspecting the workload. - Monitoring these signals needs no root.
/proc/meminfoand/proc/pressure/memoryare readable by everyone, and unprivileged users can create PSI triggers as long as the window is a multiple of 2 seconds. Run the agent as an ordinary user rather than giving it root.
In an interview
How this gets asked in an interviewpreparation
Usually phrased as free -m shows 90 MB free on a 2 GB server. Is it running out of memory?
What a strong answer contains Not from that number. free counts unused memory, and Linux fills the rest with page cache it reclaims on demand. Look at available — MemAvailable, the kernel's estimate of what a new process can get without swapping. Then look for pressure as activity: swap-in and swap-out in vmstat or sar -W, and stall time in /proc/pressure/memory. A small free figure and swap in use can both be harmless history.
The follow-up "Why not just drop the caches?" Because the kernel already gives them back when memory is needed, and dropping them throws away data that then has to be read from disk again — the kernel documentation recommends against it outside testing.
Sources
The behaviour this page describes, as documented by the projects themselves.
- Linux man pages — free(1) (Debian trixie)
- Linux man pages — vmstat(8) (Debian trixie)
- Linux man pages — sar(1) (Debian trixie)
- Linux man pages — proc_meminfo(5) (Debian trixie)
- Linux man pages — mlock(2) (Debian trixie)
- Linux kernel — Documentation for /proc/sys/vm/ (drop_caches)
- Linux kernel — Memory management concepts overview
- Linux kernel — Control Group v2
- Linux kernel — kernel parameters (psi=)
- Linux source v6.12 — mm/page_io.c
- Kubernetes — Node-pressure eviction
- Kubernetes — About cgroup v2
- Linux man pages — free(1)
- Linux kernel — /proc/meminfo
- Linux kernel — PSI: Pressure Stall Information
Did this get you to an answer?
No text box on purpose — please do not paste production logs anywhere
Something wrong or out of date? Report it