A memory leak happens when something grows with every request and the server never frees it. A Node server runs for days, so this growth slowly uses up all the memory.
Typical causes:
- Caches or
Maps at the module level with no size limit and no TTL (time to live: how long an entry stays before it is removed). - Event listeners added for each request or connection to an emitter that lives a long time, and never removed.
setIntervaltimers that are never cleared and hold on to large objects.- Closures that keep the request or response objects alive after the request has ended.
- Per-request data stored in global variables.
- Promises that never settle. They keep their callbacks alive in memory.
Fixes:
- Limit caches with an LRU (Least Recently Used: it removes the oldest-used entries first) and a TTL, or use an external cache like Redis.
- Remove listeners with
offor anAbortSignal. - Clear timers when the work finishes or the server shuts down.
- Don't keep references to request objects after the request ends.
- In-memory caches with no size limit are a common leak.
- Listeners added for each request and never removed cause leaks.
- Intervals that are never cleared and long-lived closures keep memory alive.
- Globals that hold per-request data, and promises that never settle, also leak.
- Fix leaks by limiting caches and cleaning up listeners and timers.
Read more