Install
openclaw skills install @pruthviishere/macos-memory-triageDiagnose why a Mac (especially one running Claude Code, other AI coding tools, or several Electron-based IDEs at once) is slow, hanging, or freezing due to memory pressure and swap thrashing. Covers reading real swap/memory numbers, finding MCP-server and plugin process bloat, spotting orphaned or d
openclaw skills install @pruthviishere/macos-memory-triageThis skill inspects live system state and then stops or disables things. That second part is real — it changes what's running on the machine. Because of that:
ps line before a kill is cheap insurance against it.ps line for a process (command, args, start time) immediately before killing it, so the person approving the command knows what they're actually stopping.npm's download cache) all count as safe: the thing comes back on its own or with a simple restart/reinstall. Deleting an application, uninstalling a package, removing user files, or any rm -rf outside the specific cache paths named below does not count as safe and is out of scope for this skill — do not do it, and do not suggest it as an escalation.kill (or kill -9) doesn't make something go away for good, that is a signal to investigate, not a license to escalate. See "When a killed process comes back" below. The answer is never "delete the app that owns it."Keep this framing in the conversation with the user, briefly, before running remediation commands — they should know this is a "review everything" operation, not a "run and forget" one.
Vague "it feels slow" isn't a diagnosis. Start with hard numbers, all read-only:
# Total RAM
sysctl hw.memsize | awk '{printf "%.1f GB\n", $2/1073741824}'
# Swap usage - the single most telling number
sysctl vm.swapusage
Rule of thumb: swap being heavily used (say, more than half of whatever total swap macOS has allocated) means the machine has been under real memory pressure — not just "a lot of processes," but genuinely not enough RAM for what's currently running. That distinction matters for what you recommend later: killing a handful of processes helps only if it actually closes the RAM gap.
# Top processes by memory, system-wide (not just one app's processes)
ps aux | sort -rk4 | head -25 | awk '{printf "%-8s %-6s %-6s %s\n", $2, $3"%", $4"%", $11" "$12" "$13" "$14}'
Look at this list with the user before assuming anything is "the problem" — a process using CPU briefly is normal; a process quietly holding a large %MEM for hours is the more interesting signal.
Tools like Claude Code, and similar MCP-based agent tools, can spawn a separate background server process for every enabled plugin/extension — often via npx, which does a fresh package resolution on each start. Left running across many app windows, these add up fast on a memory-constrained machine.
# List everything that looks like it's an MCP server or an npx-launched helper
ps aux | grep -iE "npx|npm exec|mcp" | grep -v grep
If the tool in question stores its enabled-plugin list in a config file (for Claude Code, that's enabledPlugins in ~/.claude/settings.json), read it and cross-reference: plugins the user doesn't actually use are pure overhead — each one is a standing process even when idle.
Also check how many separate sessions/windows of the tool are running, and for how long:
ps -eo pid,etime,command | grep -i "<tool process name>" | grep -v grep
A session that's been running for many hours in a forgotten terminal tab is holding memory the whole time for no benefit. That's usually a bigger win to close than any single background helper process.
Package manager caches are, by design, fully regenerable — clearing them frees disk space (and indirectly reduces cold-start overhead) with zero functional loss, since the tool just re-downloads what it needs next time.
du -sh ~/.npm/_npx ~/.npm/_cacache ~/.npm 2>/dev/null
If these are large (multiple GB is common after months of use), clearing is safe:
npm cache clean --force
rm -rf ~/.npm/_npx/*
This is disk cleanup, not RAM relief — mention that distinction to the user so they don't expect swap to drop from this step alone.
All of these are reversible. Show the exact command and what it targets before running it, and confirm the target process/plugin with the user first.
false in its config file rather than deleting the entry. The user (or you, on request) can flip it back on any time. Changes like this typically need a full quit-and-relaunch of the app to take effect — killing the app's existing processes won't retroactively apply a config change.kill <pid> # ask nicely first
kill -9 <pid> # only if it ignores the polite request
kill approach, same confirm-first rule.Sometimes a process respawns within a second of being killed. That means something else is supervising it — either the OS's service manager, or a still-running parent application that treats it as a child worker it's responsible for keeping alive. Fighting this with repeated kill calls doesn't work and isn't the fix.
Check if it's an OS-level service:
launchctl list | grep -i "<name>"
If it shows up, it likely has a launch agent plist under ~/Library/LaunchAgents/. Unloading it stops the process and the auto-restart behavior, and it's fully reversible:
launchctl unload ~/Library/LaunchAgents/<the-plist-file>.plist
# to bring it back later:
launchctl load ~/Library/LaunchAgents/<the-plist-file>.plist
Check if it's a child of a running app: Some apps — IDEs and dev tools in particular — launch their own dedicated helper processes for automation or background tasks (a giveaway is a process that looks like a normal system binary but is started with unusual custom flags, e.g. a browser launched with its own private profile directory rather than the user's regular one). If the parent app is still running, it will simply relaunch the child. In this case the honest options are:
Quitting an app is still fully reversible (relaunch it anytime) — it is not the same thing as deleting or uninstalling it, and that distinction is the one to hold onto here. Never respond to a respawning child process by suggesting the parent app be deleted or uninstalled; that's outside what this skill does, and it's a wildly disproportionate response to "a process won't stay dead."
After cleanup, re-check swap:
sysctl vm.swapusage
If it's still high, say so plainly rather than declaring victory. Process cleanup has a ceiling on a memory-constrained machine — if normal daily usage (a couple of dev tools, a browser, the OS itself) already exceeds installed RAM, no amount of killing background helpers permanently fixes that; it only buys some headroom until the same usage pattern fills it back up.
What actually helps beyond that point:
There is no user-facing macOS setting to manually "increase swap" the way some other operating systems allow. macOS already grows its swap files on disk automatically as needed; adding more swap doesn't address the underlying slowdown, because the slowdown is the swapping itself, not a shortage of swap space.
| Action | Allowed here? | Why |
|---|---|---|
| Read memory/swap/process stats | Yes | Read-only |
| Kill/stop a confirmed process | Yes, with confirmation | Reversible — relaunches on demand |
| Disable a plugin/extension flag | Yes, with confirmation | Reversible — flip it back anytime |
| Clear a package manager cache (npm/npx etc.) | Yes | Regenerates automatically on next use |
| Unload a launchd agent | Yes, with confirmation | Reversible via launchctl load |
| Quit a running application | Yes, with confirmation | Reversible — relaunch anytime |
| Delete/uninstall an application | No | Not reliably recoverable |
| Delete user files or documents | No | Not reliably recoverable |
rm -rf outside named cache paths | No | Too easy to hit something that isn't regenerable |