free Command in Linux: Complete Guide to Memory Usage Display and Parameters

free command in Linux and it perimeters

Nothing causes more confusion for people new to Linux than opening free and seeing almost no “free” memory available, even on a system that’s barely doing anything. I remember genuinely panicking about this early in my career before understanding how Linux actually manages memory. free is simple to run but easy to misread — so let’s go through it properly, column by column.

What is the free Command?

free displays a summary of total, used, and available system memory, including both physical RAM and swap space. It reads its data from /proc/meminfo, the kernel’s live memory statistics interface, and presents it in a condensed, human-friendly table.

Basic Syntax

free [OPTIONS]

A Real Example

free -h

Actual output from a test system:

               total        used        free      shared  buff/cache   available
Mem:           3.9Gi       197Mi       3.8Gi       4.2Mi        46Mi       3.7Gi
Swap:             0B          0B          0B

Understanding Every Column

This is the part that actually matters:

  • total — total installed physical RAM (or configured swap size)
  • used — memory currently in active use by running processes and the kernel itself, calculated as total - free - buff/cache (roughly; modern free accounts for reclaimable slab memory too)
  • free — memory that is completely unused and immediately available with zero overhead
  • shared — memory used by tmpfs and shared memory segments (/dev/shm, inter-process shared memory)
  • buff/cache — memory used for disk buffers and the page cache. This is memory the kernel is using to cache recently read/written files for speed, but it is reclaimable — the kernel will drop it instantly if an application needs that memory instead
  • available — the single most useful number on this whole screen: an estimate of how much memory is actually available for starting new applications, accounting for reclaimable cache, without triggering swapping

The Number Everyone Misreads

Look at that free column again: 3.8Gi free. Someone new to Linux might read this and assume the system is barely using any memory at all — but the real story is in used (197Mi) and available (3.7Gi). The buff/cache column here is only 46Mi in this example because it’s a freshly booted test system with almost nothing cached yet; on a real production server that’s been running for weeks, buff/cache frequently grows to consume nearly all otherwise-unused RAM, and that is completely normal, healthy behavior — not a memory problem.

The rule I always tell people: never judge memory pressure from the free column. Always look at available instead. Linux is deliberately designed to use “unused” RAM for caching, on the principle that unused memory is wasted memory — and it will release that cache instantly the moment an application actually needs it.

Common Parameters

OptionDescription
-hHuman-readable output (auto-scaled units: Ki, Mi, Gi)
-bShow output in bytes
-kShow output in kibibytes (default)
-mShow output in mebibytes
-gShow output in gibibytes
-w“Wide” mode — splits the buff/cache column into separate buffers and cache columns
-s <seconds>Continuously refresh output every N seconds, like a simplified top for memory only
-c <count>Combined with -s, limits the number of refresh iterations
-tAdd a totals row summing memory and swap together
-lShow detailed low and high memory statistics (mostly relevant on older 32-bit systems)

Practical Examples

Human-readable, one-shot check (my most common invocation)

free -h

Continuously monitor memory every 2 seconds

free -h -s 2

I use this when actively watching memory behavior during a load test or while reproducing a suspected leak — it’s a lightweight alternative to keeping a full top session open.

Watch memory for a fixed number of iterations, useful in scripts

free -h -s 5 -c 6

Refreshes every 5 seconds, stops after 6 total readings (30 seconds total).

Wide format, separating buffers from cache

free -w -h

Output format:

               total        used        free      shared     buffers       cache   available
Mem:           3.9Gi       197Mi       3.8Gi       4.2Mi        12Mi        34Mi       3.7Gi
Swap:             0B          0B          0B
  • buffers — raw block device I/O buffers
  • cache — page cache for file contents

This distinction rarely matters day-to-day, but it’s occasionally useful when specifically diagnosing block-device-level I/O caching behavior versus file-level caching.

Show a combined memory + swap totals row

free -h -t

How free Works Internally

free is a thin, fast reader of /proc/meminfo, a virtual file the kernel keeps continuously updated with live memory statistics. You can view the raw source data yourself:

cat /proc/meminfo | head -10

This file contains dozens of fields (MemTotal, MemFree, MemAvailable, Buffers, Cached, SwapTotal, SwapFree, Slab, SReclaimable, and many more), and free essentially aggregates and formats a curated subset of them into the compact table you see.

The available column specifically is computed using a kernel-provided estimate (MemAvailable in /proc/meminfo, introduced in Linux 3.14) that accounts for reclaimable page cache and slab memory, giving a genuinely more accurate picture of “how much memory could I actually use right now” than a naive free + cached calculation would.

Real-World Use Cases

Pre-deployment capacity check:

free -h

Before deploying a memory-hungry service, I always check available to confirm there’s realistically enough headroom, rather than trusting total alone.

Diagnosing swap thrashing:

free -h
vmstat 1 5

If Swap: used is climbing and vmstat‘s si/so (swap in/out) columns show constant activity, that’s a strong signal the system is under real memory pressure and actively swapping — a serious performance problem, unlike high buff/cache which is harmless.

Confirming a memory leak’s system-wide impact over time:

free -h -s 10 -c 60 | tee memory-log.txt

Logs memory usage every 10 seconds for 10 minutes, which I then review to see if available memory is steadily trending downward — a real leak signature, as opposed to normal cache growth which plateaus.

Quick swap configuration check:

free -h
swapon --show

Combining these tells me both how much swap exists and how it’s currently being used.

Troubleshooting Common Issues

“free” column looks alarmingly low, but the system feels fine — This is almost always just healthy page cache usage. Check available instead of free.

“available” is low and the system is genuinely sluggish — This is real memory pressure. Check for a runaway process with ps aux --sort=-%mem | head, and investigate whether it’s an actual leak or just a legitimately memory-hungry workload that needs more RAM or better tuning.

Swap shows 0 total — Some systems (particularly containers, and increasingly some cloud server images) are configured with no swap at all, often intentionally for performance-predictability reasons. This isn’t a free problem — it reflects the actual system configuration, verifiable with swapon --show or checking /etc/fstab.

Output units look wrong compared to what you expected — Remember -h uses binary units (Ki/Mi/Gi = 1024-based), which is standard for free, whereas some other tools report decimal (K/M/G = 1000-based) units. This can cause small apparent discrepancies when cross-checking against other utilities.

Performance Optimization Considerations

  • Don’t chase “low free memory” as a problem to fix — it’s frequently a sign of a healthy, well-utilized system, not a resource shortage.
  • Focus tuning efforts on available memory trends over time and actual swap activity (si/so in vmstat), which are the metrics that genuinely correlate with real performance problems.
  • For memory-sensitive workloads (databases, JVM-based apps), tune the application’s own memory limits based on available memory headroom, leaving comfortable room for the kernel’s page cache to continue doing its job.

Security Implications

free‘s output itself carries minimal direct security risk — it’s simply system-wide aggregate memory statistics, without process-specific detail. That said, unusual memory patterns (a sudden, sustained drop in available with no obvious application explanation) can sometimes be an early indirect signal of a compromised process consuming resources (like a cryptominer), which is worth folding into broader monitoring and alerting rather than treating free in isolation.

free vs. Related Commands

CommandDifference
vmstatShows memory alongside CPU, I/O, and swap activity over time, better for spotting trends and swap thrashing
top / htopShow memory summary plus per-process memory breakdown together in one live view
/proc/meminfoThe raw kernel data source free itself reads from, with many more granular fields
smemReports more accurate per-process memory usage accounting for shared memory (PSS), avoiding the double-counting issue with plain RSS
numastatMemory statistics broken down by NUMA node, relevant on multi-socket servers

Compatibility Across Distributions

free is part of procps/procps-ng and is present on virtually every Linux distribution by default — Ubuntu, Debian, RHEL, CentOS, Fedora, Arch, openSUSE. Output format and available flags are consistent across all of them, since they all read from the same standardized /proc/meminfo kernel interface. The one notable difference is the available column itself, which requires a kernel version of at least 3.14 (released in 2014) — on genuinely ancient kernels, this column may be absent or computed less accurately by free itself as a fallback estimate.

free Inside Containers — A Common Gotcha

This is one of the most important practical caveats about free, and it catches a lot of people off guard: inside a Docker or other cgroup-constrained container, free frequently reports the host’s total memory, not the container’s actual memory limit. If you’ve set a container memory limit of 512MB via docker run --memory=512m, running free -h inside that container may still show the full host memory (say, 64GB), because free is reading /proc/meminfo, which in many configurations reflects the underlying host’s kernel view rather than the container’s cgroup-imposed limit.

To see the actual enforced limit and current usage from within a cgroup-constrained environment, check the cgroup interface directly instead:

# cgroup v2
cat /sys/fs/cgroup/memory.max
cat /sys/fs/cgroup/memory.current

# cgroup v1 (older systems)
cat /sys/fs/cgroup/memory/memory.limit_in_bytes
cat /sys/fs/cgroup/memory/memory.usage_in_bytes

I’ve seen real incidents where a containerized application appeared to have plenty of “free” memory according to free -h, right up until it hit its actual cgroup limit and got OOM-killed without warning — because nobody was looking at the number that actually mattered. If you’re debugging memory issues inside a container, always check the cgroup limits directly rather than trusting free‘s output at face value.

Understanding the OOM Killer’s Relationship to free’s Numbers

When a system runs critically low on available memory, the Linux kernel’s Out-Of-Memory (OOM) killer steps in and forcibly terminates a process to reclaim memory, based on a scoring system (visible per-process in /proc/[pid]/oom_score). This is a last-resort mechanism, and by the time it activates, free‘s available column would already be showing a very low number for some time beforehand. I always treat available dropping toward zero as an early warning sign, well before actual OOM kills start happening — proactive monitoring based on trends in available memory is far better than reactively investigating after the OOM killer has already taken down a process.

dmesg | grep -i "killed process"
journalctl -k | grep -i "out of memory"

These commands show a history of any OOM kill events, which I always cross-reference against free/memory monitoring history when investigating an application that mysteriously restarted or crashed.

Comparing free’s Numbers Against /proc/meminfo Directly

For genuinely deep debugging, it’s sometimes worth bypassing free entirely and reading the raw kernel data:

cat /proc/meminfo

This exposes far more granular fields than free surfaces by default — things like Dirty (memory waiting to be written back to disk), Writeback (memory actively being written back), AnonPages (memory used by processes not backed by a file), Mapped (files mapped into process memory via mmap), and SReclaimable/SUnreclaim (reclaimable vs. non-reclaimable kernel slab memory). I rarely need this level of detail day-to-day, but when chasing a genuinely subtle memory issue — like slab memory growth from a kernel-level driver bug — this raw data is where the real answers live.

Summary

free looks like the simplest command in this whole series, but it’s also the one most commonly misread. The core lesson I always pass on: ignore the raw free column, and pay attention to available instead — Linux using “spare” RAM for disk cache is a feature, not a problem, and understanding that distinction is the difference between panicking over a healthy system and correctly identifying real memory pressure when it actually happens.

References

  • Linux man-pages project, free(1): https://man7.org/linux/man-pages/man1/free.1.html
  • The Linux Kernel /proc/meminfo documentation: https://www.kernel.org/doc/html/latest/filesystems/proc.html#meminfo
  • GNU/Linux procps-ng project: https://gitlab.com/procps-ng/procps
  • Linux Kernel documentation on memory management: https://www.kernel.org/doc/html/latest/admin-guide/mm/index.html
Total
0
Shares

Leave a Reply

Previous Post
halt command in Linux and it perimeters

halt Command in Linux: Complete Guide to Stopping the System and Parameters

Next Post
fg command in Linux and it perimeters

fg Command in Linux: Complete Guide to Foreground Process Management and Parameters

Related Posts