Avoiding memory leaks in Node.js is mainly about proper memory management and cleaning up unused resources, so that the garbage collector can free memory on time.
1. Avoid Unnecessary Global Variables
Global variables stay in memory for the entire app lifecycle.
let cache = []; // risky if it keeps growing
✔ Better approach:
- Limit size
- Clear unused data
- Use scoped variables whenever possible
2. Always Clean Up Event Listeners
If you add listeners, make sure to remove them when not needed.
emitter.on("event", handler);
// cleanup
emitter.removeListener("event", handler);
✔ Tip: Use .once() if the event should run only once
3. Clear Timers Properly
Uncleared timers keep running and hold memory.
const interval = setInterval(() => {
console.log("Running...");
}, 1000);
// cleanup
clearInterval(interval);
4. Use Streams Instead of Loading Large Data
Avoid loading large files/data into memory.
❌ Bad:
const data = fs.readFileSync("largeFile.txt");
✔ Good:
fs.createReadStream("largeFile.txt").pipe(res);
👉 Streams process data in chunks → less memory usage
5. Limit Caching
Caching is useful but dangerous if uncontrolled.
✔ Best practices:
- Use size limits (LRU cache)
- Set expiry (TTL)
- Avoid storing huge objects
6. Be Careful with Closures
Closures can retain large objects unintentionally.
✔ Solution:
- Avoid holding unnecessary references
- Set unused variables to
nullif needed
7. Handle Promises Properly
Unresolved promises can hold memory.
new Promise(() => {}); // never resolved → memory leak
✔ Always resolve/reject promises
8. Avoid Circular References
Objects referencing each other unnecessarily can delay garbage collection.
✔ Keep object relationships simple and clean
9. Monitor Memory Usage
Use tools to detect issues early:
- Chrome DevTools (heap snapshot)
node --inspectclinic.js
✔ Track memory trends over time
10. Use Production Best Practices
- Restart apps periodically (PM2 clustering)
- Keep dependencies updated
- Avoid blocking code
- Validate input to prevent large payload attacks
Real-world Example
A common mistake:
- Storing user sessions in an array
- Never deleting old sessions
✔ Fix:
- Use Redis with expiry
- Clean old data automatically
Key Takeaway
Memory leaks can be avoided by cleaning up resources, limiting data growth, and writing optimized code. The goal is simple: don’t hold references to data you no longer need, so Node.js can free memory efficiently and keep your application stable.