Memory usage (also called RAM usage) is the amount of physical memory that a server, a process or a container currently occupies, measured in bytes and usually reported as an absolute value and as a percentage of installed RAM. Among server resources, it is the metric that decides whether workloads run from fast memory or are pushed into swap or terminated by the operating system.
On servers, the raw number is easy to misread. Modern kernels deliberately fill otherwise idle RAM with page cache, so a machine that shows 95 percent used may be perfectly healthy, while one at 70 percent may be close to trouble. Correct interpretation depends on separating reclaimable memory from memory that applications truly need.
How the operating system accounts for memory
An operating system divides physical RAM into pages, typically 4 KiB each, and tracks who owns every page. On Linux, the main categories are anonymous memory used by process heaps and stacks, file-backed memory that caches file contents, kernel memory such as slab caches, and free pages. Only part of this total is truly committed to applications.
The key figure on Linux is MemAvailable, an estimate of how much memory can be given to new work without swapping. It counts free pages plus the reclaimable part of page cache and slab memory. Tools such as free show it in the available column, and it is a far better health indicator than the used column.
| Category | What it holds | Reclaimable |
|---|---|---|
| Anonymous memory | Heaps, stacks, application data | Only by swapping |
| Page cache | Recently read or written file data | Yes, clean pages quickly |
| Dirty pages | Modified file data not yet written | After writeback to disk |
| Slab memory | Kernel objects such as inode caches | Partly (reclaimable slab) |
| Shared memory | tmpfs files and shared segments | Only by swapping |
| Free memory | Unused pages | Already free |
Process-level metrics: RSS, PSS and virtual size
Per-process memory usage has several definitions, and choosing the wrong one leads to double counting or underestimation. The virtual size (VSZ) includes every reserved address range, much of which is never touched. The resident set size (RSS) counts pages currently in RAM, but it counts shared libraries fully in every process that maps them.
| Metric | Definition | Typical use |
|---|---|---|
| VSZ | All mapped virtual address space | Rarely meaningful for capacity |
| RSS | Resident pages, shared pages counted fully | Quick per-process view |
| PSS | Resident pages, shared pages divided among users | Fair totals across processes |
| USS | Pages unique to the process | Memory freed if the process exits |
| Working set | Pages actively used in a recent interval | Sizing caches and containers |
For a pool of identical workers, such as PHP-FPM or Apache prefork processes, the proportional set size (PSS) gives the most honest sum. Adding RSS values for 50 workers that share a large code segment can overstate real consumption by a wide margin.
Memory usage compared with related server metrics
Memory usage interacts closely with other server resource metrics, and a diagnosis usually needs several of them together. High usage alone is not a problem; sustained reclaim pressure is.
| Metric | Relation to memory usage | Warning sign |
|---|---|---|
| Swap usage | Shows anonymous pages moved to disk | Continuous swap-in and swap-out activity |
| I/O wait | Rises when reclaim forces disk reads | Spikes while page cache shrinks |
| Memory overcommit | Allows allocations beyond physical RAM | Committed memory far above RAM plus swap |
| Pressure stall information | Time tasks wait for memory | Memory pressure above a few percent |
| Load average | Includes tasks blocked on I/O | Rising load without CPU usage |
Linux pressure stall information (PSI), exposed in /proc/pressure/memory, measures the share of time tasks were stalled waiting for memory. It answers the question that usage percentages cannot: whether the shortage is actually slowing work down.
Limits, containers and the out-of-memory killer
When memory cannot be reclaimed fast enough, the kernel invokes the out-of-memory (OOM) killer, which terminates a process chosen by its oom_score, largely based on memory size. On a database server this can stop the most important process first, so administrators protect critical services with oom_score_adj.
Containers add another layer. cgroup memory limits cap the memory of a group of processes, and the limit includes page cache charged to that group. A container can therefore be killed at its limit even when the host still has free RAM, and container memory usage reported by orchestrators often includes cache that would have been reclaimable. Setting memory requests and limits from measured working sets, not from guesses, avoids both waste and unexpected kills.
Monitoring and sizing memory in practice
Effective monitoring tracks available memory, swap activity, reclaim pressure and OOM events rather than a single used percentage. The table below lists practical thresholds; exact values depend on the workload.
| Signal | Typical alert condition | Usual response |
|---|---|---|
| Available memory | Below about 10 percent for several minutes | Investigate growth, plan more RAM |
| Swap-in rate | Sustained nonzero rate under normal load | Reduce footprint or add memory |
| Memory PSI | Rising stall time over 10-60 s windows | Check for leaks or oversized caches |
| OOM kill events | Any occurrence on production hosts | Review limits and process sizing |
| Per-process growth | Steady increase without plateau | Suspect a memory leak |
- Size worker pools from PSS: divide memory reserved for the service by the average worker footprint.
- Leave headroom for page cache, because databases and web servers depend on it for fast file access.
- Watch trends over days, since slow leaks only appear across restarts and traffic cycles.
Common mistakes when reading memory usage
The classic mistake is treating page cache as consumed memory and adding RAM or restarting services because a dashboard shows 90 percent usage. The opposite mistake is ignoring a slowly growing anonymous memory footprint because total usage looks stable while cache shrinks to compensate.
Other frequent errors include dropping caches manually as a fix, which only causes extra disk reads, setting database buffers so large that the operating system starts swapping, and comparing memory figures from tools that use different definitions, such as RSS in one dashboard and PSS in another.
Stripped to the essentials
Memory usage tells you how much of a server’s working memory is occupied. Working memory is the fast desk space where programs keep what they are using right now. If the desk is full, work has to be moved to a slow storage cabinet, and everything slows down.
The twist is that servers keep their desks intentionally full of handy copies of recently used files, because empty space helps nobody. Those copies can be cleared instantly. So the real question is not how full the desk looks, but how much space programs could get if they needed it.
Where it is applied
A hosting team runs an online shop on a virtual server with 16 GB of RAM. The dashboard shows memory usage above 90 percent, and a colleague proposes doubling the RAM. Before ordering, an administrator checks the details: about 7 GB is page cache, available memory is around 6 GB, swap activity is zero and memory pressure stays near zero.
The team concludes that the server is healthy and changes the alert to watch available memory and swap-in rate instead of used percentage. Two months later the new alert fires: one PHP-FPM worker grows steadily after each product import. The team finds a memory leak in an import extension, sets a maximum request count per worker so processes are recycled, and the upgrade is never needed.