@workingmodel/who-ate-my-ram
v1.0.0
Published
Watches your running Node processes and tells you which one is quietly eating your memory — and why.
Downloads
89
Maintainers
Readme
@workingmodel/who-ate-my-ram
Watches your running Node processes and tells you which one is quietly eating your memory — and why. Developed by Working Model.
who-ate-my-ram 7:14:02 PM interval:5s window:10m threshold:5MB/min
────────────────────────────────────────────────────────────────────────────────
PID PROCESS BAR NOW DELTA TREND STATUS
84312 express.js [████████████░░] 527.3 MB +340.1 MB +28.3/m LEAKING
91004 next-server.js [████░░░░░░░░░░] 94.2 MB +6.0 MB +0.5/m growing
77210 worker.js [███░░░░░░░░░░░] 65.5 MB +0.1 MB +0.0/m stable
⚠ express.js (PID 84312) grew 340 MB in 12.0 minutes
likely cause: EventEmitter listener accumulation
Each request likely registers a new listener without removing it. Check
.on('data'), .on('end'), .on('error') calls inside route handlers. Use
.once() or call .removeListener() / .off() when done.Install
npm install -g @workingmodel/who-ate-my-ramRequirements: Node.js 18+. macOS or Linux. No other setup.
Usage
# Watch all Node processes (default: 5s interval, 10 minute window)
who-ate-my-ram
# Faster polling, shorter window
who-ate-my-ram --interval 3 --window 5
# Focus on a single PID
who-ate-my-ram --pid 84312
# Lower the sensitivity threshold
who-ate-my-ram --threshold 2
# Machine-readable JSON output
who-ate-my-ram --json > report.jsonPress Ctrl+C to stop. A final report prints on exit with the culprit summary and a pre-filled node --inspect <pid> command for heap snapshot capture.
Options
| Flag | Default | Description |
|------|---------|-------------|
| --interval <secs> | 5 | How often to sample each process |
| --window <mins> | 10 | How far back to look when computing the trend |
| --threshold <MB/min> | 5 | Growth rate above which a process is flagged as leaking |
| --pid <pid> | — | Watch a single process by PID |
| --json | — | Output final report as JSON instead of formatted text |
| --help | — | Show help |
How it works
- Discovers all running Node processes via
ps aux - Samples RSS (resident set size) from the OS on every interval — RSS captures native allocations and Buffers that V8 heap metrics miss
- Fits a linear regression across the observation window to get a true MB/min growth slope, filtering out GC noise that makes point-in-time deltas unreliable
- Classifies each process:
stable(< 2 MB/min),growing(2–5 MB/min), orleaking(> threshold) - Pattern-matches the growth shape to one of five named leak signatures using observable signals (growth shape, CPU alongside memory, open file descriptor count)
- Reports in plain English with a specific next step
No LLM — all heuristics are deterministic. Same input always produces the same output.
Leak patterns detected
| Pattern | Signal | |---------|--------| | EventEmitter listener accumulation | Linear growth, low CPU, no periodic drops | | Timer / interval leak | Sawtooth — periodic drops but rising floor | | Stream not destroyed | Linear growth alongside climbing file descriptor count | | Buffer / cache accumulation | Chunky positive jumps or accelerating growth rate | | Closure retention | Linear growth with CPU spikes (GC running but not reclaiming) | | Memory leak (unclassified) | Consistent upward trend, no specific shape match |
Each diagnosis includes a confidence level (likely, possible, weak signal) and a concrete suggestion — not just a label.
Why This Exists
Memory leaks in Node are easy to miss and painful to diagnose. By the time something is obviously wrong, you're staring at a heap snapshot that needs a PhD to interpret. This tool watches your processes the way a sane person would — tracking growth over time, ignoring GC noise, and naming the pattern when it finds one. You get a plain-English verdict and a next step, not a wall of data to decode.
More tools →
More tools from Working Model → workingmodel.co
