Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

AI Agent Resource Hog Watcher

Stop macOS OOM crashes from taking down your agent work by sacrificing expendable GUI apps first.

This is a small macOS LaunchAgent for machines running Codex, OpenClaw, Claude Code, local agents, or other long-running AI work. It watches memory pressure trends and terminates only explicitly configured GUI app bundles when pressure gets dangerous.

It is not a generic "kill the biggest process" script. It fails closed: if it cannot prove a PID belongs inside a configured app bundle, it skips that PID.

Why

macOS already compresses memory and swaps. What macOS does not know is your policy:

  • browser tabs are expendable
  • AI agent sessions are not
  • terminal shells, SSH, OpenClaw, Codex, Python/Node workers, and launchd services should be protected

This watcher adds that policy layer.

Default Targets

Tier Apps
1 Google Chrome, Brave Browser, Safari
2 Discord, Lovable, evaOS Workbench
3 Telegram, Messages

Tier 3 is opt-in. Messaging apps can be operational lifelines, so the installer defaults to MAX_TIER=2.

Trigger Model

Primary signals:

  • vm.memory_pressure
  • vm_stat pageout rate
  • vm_stat swapout rate
  • compressor, free-page, and reclaimable-page percentages as supporting context

Low free pages and compressor churn alone are not triggers. On macOS, low free pages can be normal when inactive/file-backed memory is reclaimable. Termination requires real pageout or swapout pressure; reclaimable memory only affects severity.

The watcher suppresses repeat actions against the same app bundle for 10 minutes by default. That prevents it from fighting you if you intentionally reopen an app after it was sacrificed once.

It also skips candidate app bundles below 512MB total RSS by default. Closing a 170MB chat app is not an OOM strategy; it is collateral. The current frontmost app is protected by default.

Safety Model

The watcher:

  • resolves PID executable paths with proc_pidpath
  • ascends to the outermost .app bundle
  • reads Contents/Info.plist
  • requires exact CFBundleIdentifier match
  • revalidates the PID before hard kill
  • skips protected paths such as .openclaw, Codex, Terminal, iTerm, VS Code, Claude, and ChatGPT
  • protects the frontmost app by default
  • de-duplicates helper processes to one canonical app-level candidate per bundle
  • avoids substring matching, pkill, and killall

Verify

./agent-resource-hog-watcher.py --self-test
./agent-resource-hog-watcher.py --inventory
./agent-resource-hog-watcher.py --print-plist | plutil -lint -
./agent-resource-hog-watcher.py --dry-run --force-severity warning --interval 0.1

The forced trigger is for proof. Use it with --dry-run unless you intentionally want to test live termination.

Install

./install.sh plist
./install.sh install --yes
./install.sh status

The generated LaunchAgent runs observe-only by default:

~/Library/LaunchAgents/ai.100yen.resource-hog-watcher.plist

The installer copies the runtime script into:

~/.agent-resource-hog-watcher/bin/agent-resource-hog-watcher.py

That avoids launchd permission surprises from removable volumes, symlinked repo folders, or deleted checkouts.

Logs and status:

~/.agent-resource-hog-watcher/logs/resource-hog-watcher.log
~/.agent-resource-hog-watcher/logs/resource-hog-watcher.status.json

Optional tuning:

MAX_TIER=2 INTERVAL_SECONDS=2 ./install.sh install --yes

Arm live termination only after observing dry-run output and confirming the thresholds are right:

ARMED=1 MAX_TIER=1 INTERVAL_SECONDS=2 ./install.sh install --yes

Allow tier-3 lifeline apps only if you really want that behavior:

MAX_TIER=3 ./install.sh install --yes

Change repeat-kill suppression:

BUNDLE_COOLDOWN_SECONDS=300 ./install.sh install --yes

Change the minimum app-bundle size required before termination:

MIN_BUNDLE_RSS_MB=1024 ./install.sh install --yes

Rollback

./install.sh unload --yes
./install.sh uninstall --yes

uninstall archives the plist instead of deleting it.

Important Limits

  • This cannot save a machine if the kernel never schedules the watcher before the OOM event.
  • It does not add swap, purge caches, or tune kernel behavior.
  • It intentionally protects agent/runtime processes outside configured GUI app bundles.
  • Edit the target list before installing if these defaults do not match your workflow.

License

MIT.

About

macOS AI agent resource hog watcher that sacrifices expendable GUI apps before OOM kills agent work

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages