At one moment on a 48 GB M5 Pro, three tools described the same memory state three different ways. memory_pressure said 84% free. Searoom said 52.7% used. vm_stat reported 246,914 free pages, which is about 4 GB, or roughly 8% of the machine.
None of them is wrong. They are answering different questions, and only one of those questions is the one you actually have when you are deciding whether a model will fit.
The same instant, three readings
These readings were taken within the same minute on an otherwise ordinary desktop session: browser, editor, Slack, a few helpers. No inference workload was running.
| Source | Reading | What it is counting |
|---|---|---|
memory_pressure | 84% free | A system-wide free percentage that treats most resident pages as reclaimable |
| Searoom | 52.7% used | Active plus wired plus compressed, as a fraction of physical memory |
vm_stat free pages | 4.05 GB | Pages on the free list right now, holding nothing |
kern.memorystatus_vm_pressure_level | 1 | The kernel's own pressure state: normal |
vm.swapusage | 0 bytes | Swap actually allocated |
The spread between 84% free and 52.7% used is not a rounding difference. It is a disagreement about where the boundary sits between memory that is in use and memory you could still have.
Free memory is the least useful number
The free page count is the one most people reach for and the one that tells you least. A healthy macOS system drives free memory toward zero on purpose. Pages sitting on the free list are doing nothing. Pages holding file cache are doing something useful and can still be handed to you the moment you ask.
Apple's own definition points the same way. The Activity Monitor documentation describes the memory pressure graph as determined by free memory, swap rate, wired memory, and file cached memory together, not by any one of them, and Apple's guidance on whether a Mac needs more RAM reads that graph rather than a free-memory figure.
On the baseline reading above, free memory was about 4 GB while another 19.9 GB sat in inactive, speculative, and purgeable pages. Treating only the 4 GB as available would have been wrong by a factor of six.
What Searoom counts, and why
Searoom defines the working set as active plus wired plus compressed pages, capped at physical memory.
let used = min(total, active + wired + compressed)
let available = total - used
let cached = min(available, inactive + purgeable + speculative)Each term is chosen for a reason. Active pages are in use and not immediately reclaimable. Wired pages cannot be paged out at all. Compressed pages are the compressor's footprint, which is real physical memory the compressor is occupying on behalf of data that no longer fits uncompressed.
The categories are not Searoom's invention. They are fields of vm_statistics64, declared in XNU's osfmk/mach/vm_statistics.h as active_count, wire_count, inactive_count, speculative_count, purgeable_count and compressor_page_count. That is the same structure vm_stat prints from, so every tool on this page is ultimately reading one set of counters and disagreeing only about how to combine them.
Inactive, purgeable, and speculative pages are excluded from the working set and reported separately as cached. They are resident, but macOS can reclaim them without stalling you.
This intentionally differs from total - free, and it may differ slightly from Activity Monitor. It is built to answer one question: if I ask for another 10 GB, is that plausible without the system fighting me.
Pressure is a state, not a percentage
Memory pressure in the macOS sense is not a utilisation ratio. It is a discrete kernel state, readable as an integer:
sysctl kern.memorystatus_vm_pressure_level
# 1 = normal, 2 = warning, 4 = criticalThose three values are the set Apple exposes to applications through Grand Central Dispatch, where a memory pressure dispatch source delivers DISPATCH_MEMORYPRESSURE_NORMAL, DISPATCH_MEMORYPRESSURE_WARN and DISPATCH_MEMORYPRESSURE_CRITICAL. The sysctl and the dispatch source are two views of one kernel state.
That state is the authoritative signal, because it reflects what the kernel has decided rather than what an observer inferred. Searoom reads it and also derives a level from working-set utilisation, then keeps whichever is more severe. The thresholds for the derived tier are 70%, 85%, and 95%.
Keeping the more severe of the two matters in both directions. A machine can be at 60% working set while the kernel is already in a warning state, and it can be at 90% working set with the kernel entirely relaxed. Reporting only one of those would be misleading half the time.
What happens when you actually take the memory
Rather than reason about this, I allocated 8 GiB (8.59 GB) in a separate process, touched every page so it was genuinely resident, held it, and re-read every counter.
| Reading | Baseline | Under allocation |
|---|---|---|
| Searoom working set | 27.18 GB | 30.93 GB |
| Searoom available | 24.36 GB | 20.61 GB |
| Searoom pressure value | 0.527 | 0.600 |
memory_pressure free | 84% | 76% |
| Kernel pressure level | 1 (normal) | 1 (normal) |
| Free pages | 246,914 | 14,725 |
| Speculative pages | 52,981 | 159 |
| Purgeable pages | 33,226 | 3,786 |
| Compressor pages | 228,784 | 444,924 |
| Swap used | 0 | 0 |
Three things in that table are worth reading carefully.
The working set rose by 3.75 GB, not by the 8.59 GB I allocated. The compressor absorbed the difference: compressor pages grew by 216,140, which is 3.54 GB of additional compressor footprint holding considerably more logical data.
Free memory collapsed from 4.05 GB to 0.24 GB, and speculative pages went from 52,981 to 159. macOS reclaimed cache rather than refusing the allocation. If you were watching free memory, this looked like an emergency. Nothing was wrong.
Swap stayed at exactly zero and the kernel never left the normal state. The system absorbed a large allocation using compression and reclaim, which is the design working as intended.
Limit of this measurement
The allocated pages were zero-filled, which makes them close to perfectly compressible. That is why 8.59 GB of allocation produced only 3.75 GB of working-set growth. Model weights are not compressible in this way, so a 15 GB model will not shrink under the compressor the way this test did. Treat the mechanism here as real and the compression ratio as an artefact of the test data.
Which number answers your question
If the question is whether another model will load, read available memory and the kernel pressure state together, and treat sustained swap I/O as the signal that you have gone too far.
Swap allocation on its own is weak evidence. macOS can hold swap allocated long after the pressure that created it has passed. Swap throughput, measured as bytes per second of swap-in and swap-out, is what correlates with the stall you can feel. That distinction is large enough to deserve its own article.
The short version: available memory tells you what you can ask for, the pressure state tells you what the kernel thinks, and swap I/O tells you whether you already lost.
Reproduce this
Every number above came from tools already on your Mac, plus one Searoom command.
sysctl kern.memorystatus_vm_pressure_level
sysctl vm.swapusage
vm_stat
memory_pressure
Searoom --dump-sampleSearoom --dump-sample prints one JSON sample on stdout and exits. It takes two internal readings first, because rate-derived values such as swap I/O have no previous counter to subtract on a cold start and would otherwise report zero.
If you publish a result from this, name the Mac, the macOS build, the Searoom version, and the workload. A memory reading without those is not reproducible, and on this subject a number nobody can reproduce is worth very little.
The canonical definitions for every value discussed here live in the metric reference.