DEV Community

Cover image for Debugging Memory Leaks in Node.js and PHP 🧠
Chaitanya Rai
Chaitanya Rai

Posted on

Debugging Memory Leaks in Node.js and PHP 🧠

🧠 Debugging Memory Leaks in Node.js and PHP — Track Down Hidden Performance Killers

Have you ever restarted your app every few hours because it was “just using too much memory”? 😅

That’s usually a memory leak — when your application keeps holding onto data it no longer needs.

In this guide, we’ll explore how to detect and fix memory leaks in both Node.js and PHP, using practical tools like Chrome DevTools and Xdebug.


💡 What is a Memory Leak?

A memory leak happens when your program allocates memory and never releases it, even when that data is no longer used.

Over time, memory usage grows, performance slows, and eventually — 💥 your process crashes.

Imagine this simple analogy:

You’re putting items into a bag, but never taking anything out.

Eventually, the bag bursts.


🧩 Common Causes

Cause Example
Unreferenced objects kept alive Global variables holding large data
Event listeners not removed element.addEventListener() without cleanup
Caching gone wrong Storing too much in memory-based cache
Long-running loops or intervals setInterval without clearInterval
Circular references Two objects referencing each other indefinitely

🟢 Debugging Memory Leaks in Node.js

1️⃣ Check memory usage in real time

node --inspect yourApp.js
Enter fullscreen mode Exit fullscreen mode

Then open chrome://inspect in Chrome → click "Memory" tab → take a heap snapshot.

You can compare snapshots over time to see which objects keep growing.

2️⃣ Use process.memoryUsage()

You can log memory usage periodically:

setInterval(() => {
  const used = process.memoryUsage();
  for (let key in used) {
    console.log(`${key} ${(used[key] / 1024 / 1024).toFixed(2)} MB`);
  }
}, 5000);
Enter fullscreen mode Exit fullscreen mode

If the heap keeps increasing even under a steady workload, you likely have a leak.

3️⃣ Detect leaks with clinic.js or memwatch-next

npm install -g clinic
clinic doctor -- node app.js
Enter fullscreen mode Exit fullscreen mode

or

npm install memwatch-next
Enter fullscreen mode Exit fullscreen mode
const memwatch = require('memwatch-next');
memwatch.on('leak', (info) => console.log('Memory leak detected:', info));
Enter fullscreen mode Exit fullscreen mode

##🐘 Debugging Memory Leaks in PHP

PHP scripts usually die after each request, so memory leaks are less common — but long-running workers (like Laravel Queues or Daemon scripts) can still leak memory.

1️⃣ Enable Xdebug profiling

Add this in php.ini:

xdebug.mode=profile
xdebug.output_dir="/tmp/xdebug_profiles"
Enter fullscreen mode Exit fullscreen mode

Then run your script. Use tools like QCacheGrind or Webgrind
to visualize memory usage and function calls.

2️⃣ Monitor memory in code

You can track memory usage directly:

echo memory_get_usage(true) . " bytes\n";
Enter fullscreen mode Exit fullscreen mode

Watch for continuous growth in long loops or workers:

while (true) {
    doSomething();
    echo memory_get_usage() . "\n";
    sleep(1);
}
Enter fullscreen mode Exit fullscreen mode

3️⃣ Common PHP Leak Sources

  • Unclosed database connections
  • Huge arrays kept in memory
  • Static variables holding data between iterations
  • Recursive functions not returning

To fix these, always:

  • Unset unused variables (unset($var))
  • Close DB or file handles
  • Use generators (yield) for large datasets

🧹 Prevention Strategies

✅ Avoid global variables
✅ Use weak references or caches with size limits
✅ Always remove event listeners
✅ Test in a long-running environment (not just one request)
✅ Automate leak checks in staging

🚀 Wrapping Up

Memory leaks are sneaky — they don’t crash your app immediately but slowly drain resources until everything slows down.
By using profiling tools, logs, and heap snapshots, you can catch them before they reach production.

Remember:

Debugging is not just fixing bugs — it’s understanding why they happened.

💬 Have you ever debugged a real memory leak?
Share your story (and pain 😅) in the comments!

Top comments (0)