memscope · field log home · the story · github

Eight days.
3,710 guard passes.
Here is everything it did.

One 16 GB M4 MacBook Pro running agentic development all day. No curated demo — this is the whole log, including the parts that complicate the story.

3,710guard passes since 13 Aug
45dead tool-fleets reaped
4abandoned sessions closed
0wrongful kills
1system freeze under memory exhaustion (24 Aug)
0.24 sguard cost per pass, 4.3 MB peak

Day by day

DayPassesReapedClosedSwap range
13 Aug3141—79–85%
14 Aug3981264–96%
15 Aug2760—71–93%
16 Aug4010—72–90%
17 Aug7192173–98%
18 Aug5780—83–98%
19 Aug7191—83–100%
20 Aug5880—91–99%

Day one cleared a backlog that had been accumulating for days: 41 dead fleets, ~600 MB resident — and about 4 GB of pinned swap released within minutes. After that the shape changes completely. Leaks still happen (1, 2, 1 on later days) and get caught the same day, usually within the two-hour window. Accumulation went from a multi-day pile-up to roughly half a tree per day.

What the data proves — and what it doesn't

Supported by the log

  • The detector works: 45 dead fleets found and killed across 3,710 passes.
  • The safety contract holds at scale: zero wrongful kills. No live session, no app, nothing with a living parent was ever touched.
  • Steady state is real: after the backlog cleared, orphan accumulation stays near zero without any manual intervention.
  • The guard is nearly free: 4.3 MB peak, 0.24 s per silent pass (~1.8 s on the at-most-twice-hourly passes that notify), nothing resident in between.

Not proven

  • No control group. The same person also started paying attention to session sprawl that week. Nothing separates the tool's effect from the habit's.
  • n = 1. One machine, one user, one workload.
  • "No more force-quits" is only partly instrumented. macOS keeps its kill log for about 20 hours here — far too short to compare against the week before.
  • The machine still went down. On 24 August it froze hard at 98% swap and had to be restarted. Reaping garbage does not save a machine that is structurally overloaded. See below.
  • Swap pressure did not fall over the eight days. See below.
  • The reclaimed-MB figures are understated. Until 20 Aug memscope sized processes with ps RSS, which counts only pages still in RAM. See the correction below.

The uncomfortable number

If the claim were "memscope lowers memory pressure," this log would refute it. Swap started the week around 85% of an 11 GB swapfile. Today it sits at 96% of a 29.7 GB one — roughly 28 GB paged out, against 16 GB of physical RAM.

The honest claim is narrower, and it is the one worth making: memscope removes work that already finished. It does not shrink the work you are still doing. Live load grew all week — more sessions, more tools, more tabs — and swallowed the winnings.

That distinction turns out to be the useful part. With the dead weight provably gone — eight days of near-zero orphan accumulation — whatever pressure remains is real demand. That is a much better number to take to a hardware decision than one inflated by ghosts.

The night it went down anyway

On 24 August, five days into the guard running, the machine froze completely — cursor included — and had to be restarted. macOS had already rolled its own logs by the time we looked, so memscope's metrics are the only record of it:

18:13  swap 96%   resident 6.6 GB
18:15  swap 98%   resident 6.7 GB   ← peak; the machine wedges shortly after
18:17  swap 96%   resident 7.2 GB
       ──── six minutes, no passes: system down ────
18:23  swap 50%   resident 8.2 GB   ← swap files recreated: it rebooted
18:35  swap 91%   resident 11.7 GB  ← back under pressure within 12 minutes

memscope found zero orphans that day. There was no garbage left to collect; every byte of that pressure was live work. That is the honest verdict on what a reaper can and cannot do: it removes finished work, and when finished work is already at zero, it has nothing left to give. A tool that collects garbage cannot rescue a machine whose live workload exceeds its RAM.

It is also the clearest evidence on this page for the opposite conclusion — that this particular machine is genuinely too small for this particular workload, and no amount of hygiene changes that.

A correction we had to make

On day eight a screenshot showed a node process at 6.5 GB that memscope's own census reported as a rounding error. The cause: memscope sized processes with ps RSS, which counts only pages still resident in physical RAM. On a machine that has swapped 27 GB out — precisely the machine this tool is for — RSS is close to meaningless:

pid 49225   Activity Monitor: 5,393 MB    ps RSS: 10 MB    ← 500x apart

memscope now reports physical footprint (resident + compressed + swapped), the same figure Activity Monitor shows. Two consequences for the numbers on this page, stated plainly: the ~575 MB "reclaimed" on day one is understated — it counted only the resident pages of those 41 dead trees, not what they held in compression and swap. The ~4 GB of swap released minutes later is the better indicator of their real size, and it cannot be recovered exactly, because the processes are gone. The kill decisions themselves were never affected: orphans are identified by parentage and age, never by size.

The same screenshot found the machine's two largest processes: forgotten react-scripts dev servers, 5.4 GB and 3.2 GB, running 21 and 8 hours on branches nobody was looking at. Both had living parents, so memscope will never touch them. That is the honest boundary of what a reaper can do — and an argument for reading the census yourself.

What the kernel says

macOS logs every memory kill. In the window it still retains, running Chrome, Cursor, VS Code, two AI assistants, a bot and Excel at once:

# jetsam kills, by reason
JETSAM_REASON_MEMORY_LONGIDLE          3,684   ← routine idle daemon reaping
JETSAM_REASON_MEMORY_PERPROCESSLIMIT       9   ← Apple daemons hitting own caps
JETSAM_REASON_MEMORY_VMPAGESHORTAGE        0   ← system out of memory
JETSAM_REASON_MEMORY_HIGHWATER             0   ← system out of memory

Zero system-pressure kills in the ~20 hours macOS still retains — but note that the 24 August freeze happened outside that window, and a total system wedge leaves no jetsam record at all. Absence of kills is not absence of trouble.

Today's machine, unedited

$ memscope receipt

WHAT IS RUNNING
28 apps · 213 processes · 50.5 GB footprint · 18.7 GB swapped
footprint = resident + compressed + swapped (what Activity Monitor shows).
Processes share memory, so per-app figures sum above physical RAM.

  Google Chrome                  12.18 GB   46 proc
  Visual Studio Code              4.68 GB   20 proc
  agent tooling (node/MCP)        4.56 GB   82 proc
  Claude                          2.45 GB   13 proc
  Cursor                          2.30 GB   14 proc
  Claude Code sessions            0.50 GB    4 proc

WHAT IS ALREADY DEAD
No zombie process trees. Every process above has a living parent.
(guard has reaped 45 trees to date — this machine is being kept clean)

82 tool processes for 4 sessions, 4.6 GB. That is the fan-out this whole thing is about — and none of it is dead any more.

Run it on yours

git clone https://github.com/ghodeaniket/memscope && cd memscope
./memscope.sh receipt          # what you are running, and what of it is dead
./memscope.sh guard --dry-run  # the kill list, before you grant anything

Read-only until you install the guard. If it finds nothing, you have learned something too — your pressure is live work, and the upgrade is the honest answer.