On November 14 a 48 GB Mac showed "your system has run out of application memory" while a pile of coding agents was running. The odd part is that free memory had read 77 to 79 percent all morning. Swap was at 14.4 of 15 GB.
Our guard had a rule that said swap size alone is never pressure, and for good reason. macOS adds swap files as it needs them and leaves cold pages in them, so a big swap number on a healthy Mac is common. We took that too far. That was the bug. "Large swap is not pressure" is true. "Nearly full swap is not pressure" is not.
#
The fix
The pressure check now treats swap as a signal only when both things hold: at least 8 GB is in use, and the swap area is mostly full. At 80 percent it warns, and at 90 percent it is critical.
const SWAP_FULL_MIN_MB = 8192;
const SWAP_FULL_WARN_PCT = 80;
const SWAP_FULL_CRITICAL_PCT = 90;
const swapFull = memory.swapUsedPct != null && memory.swapUsedMB >= SWAP_FULL_MIN_MB;
if (swapFull && memory.swapUsedPct >= SWAP_FULL_CRITICAL_PCT) raise('critical', `swap is ${Math.round(memory.swapUsedPct)}% full`);
else if (swapFull && memory.swapUsedPct >= SWAP_FULL_WARN_PCT) raise('warn', `swap is ${Math.round(memory.swapUsedPct)}% full`);
The 8 GB floor matters. A 1.9 GB swap that is 95 percent full is just a small swap file, and we have a test that keeps it at normal.
The second thing we found was a rounding bug. The percentage was rounded to a whole number when we read it, so 89.5 percent became 90 and tipped over into critical. We now keep the raw number for the comparison and round only when printing the reason. There is a test for 89.5 percent staying a warning and 79.6 percent staying normal.
#
What the guard does about it
Before this, the cleanup could only stop leftover agent processes. Now, if memory is critical and nothing is left to stop, it shows one notice that names the reason and the three biggest owners, for example "swap is 94% full (14378 MB)... most is held by Codex 15.5 GB (318 processes), Claude 8.5 GB (131 processes), Google Chrome 4.2 GB (40 processes)". It shows that at most every 30 minutes, and if macOS refuses to show the notification, the 30 minute timer is not started.
#
Check your own Mac
sysctl vm.swapusage
memory_pressure | tail -1
If the swap line shows several gigabytes used and close to the total (ours was 14.4 of 15 GB), and memory_pressure reports less than about 20 percent free, you are near the wall no matter what the free memory figure says. A small swap area that is nearly full, like 1.9 GB at 95 percent, is normal on its own.
The guard is open source: https://github.com/IgorGanapolsky/mac-yolo-safeguards