skip to content

On a Linux server with 32 GB of RAM, `free` reports only about 200 MB free, several gigabytes under buff/cache, and 20 GB available. Is that machine short of memory, and what is the kernel doing with the RAM?

level: juniorimportance: must knowfreq 72%

answer

  1. free memory is wasted memory
  2. cache is borrowed, not consumed
  3. clean pages evict instantly
  4. MemAvailable, not MemFree
  5. dirty pages need writeback first

basics

~20 s

No. Linux spends otherwise-idle RAM on page cache for file data and reclaims it on demand, so near-zero free memory is normal and healthy. The number that matters is available, which estimates what a new process could still get.

solid answer

~50 s

Free memory on Linux is not a health metric — it is memory the kernel has not yet found a use for. Anything read from or written to a file passes through the **page cache**, and the kernel keeps those pages around because RAM sitting empty buys nothing. A clean cached page can be handed to a new allocation immediately, so cache is *borrowed*, not consumed. That is why `free`'s **available** column exists: since Linux 3.14 the kernel exports `MemAvailable` in `/proc/meminfo`, an estimate of how much a new workload could obtain without swapping, counting reclaimable cache and slab but subtracting the pages it cannot free. With 20 GB available out of 32 GB, this box has plenty of headroom. I would only worry if *available* were small, or if the machine were faulting pages back in constantly — that is memory pressure; a low `free` figure on its own is not.

code

bash · 1 line
bash
grep -E '^(MemTotal|MemFree|MemAvailable|Cached|Shmem|Dirty):' /proc/meminfo

go deeper

for a junior

Know that Linux deliberately fills unused RAM with cached file data and gives it back when something needs it. Say plainly that you would read the available column, not the free one.

for a middle

Explain the mechanics: file reads and writes populate the page cache, clean pages are dropped for free, dirty pages need writeback first, and MemAvailable estimates what is genuinely obtainable.

for a senior

Show that you monitor the right signal. Argue from available memory, refault rates and memory pressure stalls rather than free bytes, and push back on alerts and capacity models built on MemFree.

for a principal

Own the consequence for platform policy: which memory metric your fleet alerts on, how cache-heavy workloads are sized against cgroup limits, and why a cache-unaware capacity model systematically over-provisions RAM.

## The numbers and where they come from `free` is a thin formatter over `/proc/meminfo`. Four fields carry almost the whole story: - **MemTotal** — RAM the kernel manages (slightly less than the physical amount; firmware and the kernel image take a bite). - **MemFree** — pages on the buddy allocator's free lists right now. Untouched, unclaimed, doing no work. - **Buffers + Cached** — the page cache: in-memory copies of file contents (`Cached`) plus block-device metadata (`Buffers`). `free` prints these together as *buff/cache*. - **MemAvailable** — an *estimate*, added in Linux 3.14, of how much memory a new workload could get without pushing the system into swap. ```bash grep -E '^(MemTotal|MemFree|MemAvailable|Cached|Dirty):' /proc/meminfo ``` ## Why the kernel fills RAM with cache Every `read()` and `write()` on a regular file, and every file mapped with `mmap`, goes through the page cache. When a program reads a 2 GB log file, those 2 GB of pages stay resident after the program exits. This is deliberate: DRAM that holds nothing returns nothing, while DRAM that holds a copy of a recently used disk block can turn a future 100-microsecond disk read into a 100-nanosecond memory read. The slogan "free memory is wasted memory" is literally the design intent. The cache is not a leak because it is **reclaimable**. If a process asks for pages and the free lists are thin, the kernel's reclaim path evicts cached pages and hands the memory over. For a *clean* page — one whose contents match what is on disk — eviction costs nothing: drop it and the copy on disk is still authoritative. ## Clean, dirty, and pinned pages Not all cache is instantly free-able, which is exactly why `MemAvailable` is smaller than `MemFree + Cached`: - **Dirty pages** (`Dirty:` in `/proc/meminfo`) hold modified data not yet written to disk. They must go through writeback first, so reclaiming them costs I/O and time. `vm.dirty_background_ratio` and `vm.dirty_ratio` govern when writeback starts and when writers get throttled. - **Shared-memory and tmpfs pages** appear under `Shmem` and count as cache, but they have no backing file to fall back on — they can only be reclaimed to swap, and not at all if swap is off. - **mlocked pages** are pinned in RAM by request and never reclaimed. - The kernel also keeps a hard floor of free pages (`min_free_kbytes`, exposed via the per-zone watermarks) so it can service atomic allocations in interrupt context. `MemAvailable` folds all of that in, plus reclaimable slab (dentry and inode caches). It is a heuristic, but a far better sizing input than `MemFree`. ## When low free memory *is* a problem The honest signal is not how little is free, but how hard the kernel is working to keep it that way: - **Available is small.** If a 32 GB box reports 500 MB available, the resident set of running processes really has consumed the machine, and the next allocation will trigger reclaim or the OOM killer. - **Refaults.** Pages are evicted and immediately read back in. Each round trip is a major fault, so the workload stalls on I/O while the CPUs look idle. - **Pressure stall information.** On kernels with `CONFIG_PSI` (4.20+), `/proc/pressure/memory` reports the share of time tasks were stalled waiting on memory. A non-trivial `some avg10` there is real pressure; a low `free` figure is not. ## The trap this question is really testing Monitoring systems that alert on `MemFree` page people at 3 a.m. for a perfectly healthy machine, and — worse — teach them to "fix" it. Writing to `/proc/sys/vm/drop_caches` does free cache, but it does not create memory; it throws away work the kernel already did, and the next requests re-read from disk. It is a benchmarking aid for measuring cold-cache behaviour, not a tuning knob. The same misreading in the other direction is more expensive: sizing a container or a JVM heap from the *cache* figure, concluding an application "uses 10 GB" when most of that is file cache the kernel would surrender the moment anyone asked.

  • Which parts of the page cache can the kernel *not* hand over on demand?
    Dirty pages must be written back before their memory is reusable, so reclaiming them costs I/O. Pages pinned with `mlock` are never reclaimed. tmpfs and shared-memory pages are counted as cache but have no file to fall back to — they can only go to swap, and with swap disabled they are effectively unreclaimable. `MemAvailable` already discounts these, which is why it is lower than free plus cache.
  • Is writing to /proc/sys/vm/drop_caches ever the right move in production?
    Almost never. It discards clean cache the kernel would have surrendered anyway the instant something needed memory, and the next reads go back to disk, so latency gets worse. Its legitimate use is benchmarking — forcing a cold cache between runs so results are comparable. Reaching for it to make a dashboard look better is treating the symptom of a bad metric.
  • Why is the resident memory of a process a poor input for sizing a machine?
    Resident size counts shared pages — libraries, mapped files — once per process, so summing it across processes double-counts. It also includes file-backed pages the kernel can evict under pressure, and excludes anything swapped out. For capacity work, reason about the anonymous (non-file-backed) footprint plus headroom, and watch available memory and refault rates rather than adding resident sizes together.

saying these in an interview costs you the question

  • Says low free memory means the server needs more RAM
  • Treats the page cache as an application memory leak
  • Reads the free column instead of available when sizing
  • Counts cached file pages as the application's usage
  • Calls dropping caches a routine tuning step

context