Skip to content

Next.js memory leak in production: why your server keeps restarting

· Updated

  • Next.js
  • SSR
  • Memory Leak
  • Production

Here is how this problem usually shows up. The site works fine after a deploy. Over the next hours or days, the server uses more and more memory. Eventually it crashes, restarts, and everything looks fine again — until the next time.

Many teams handle it with a scheduled restart every few hours. That hides the symptom, but not the problem. It tends to get worse as traffic grows, and the restarts come closer and closer together.

What is actually happening

A Next.js app that renders pages on the server runs as one long-lived process. It serves thousands of requests, from many different users, without stopping.

A memory leak means that some of the work done for each request is never cleaned up. Each request leaves a little data behind. One request is nothing. A few hundred thousand requests is a crashed server.

The reason it is hard to catch: on a developer's laptop there is one user and a few requests, so the leak is too small to notice. It only becomes visible under real traffic.

Common causes

In my experience, it is usually one of a few things:

  • A "cache" that never gets emptied. Someone stores data in memory to make pages faster, but nothing ever removes old entries. It keeps growing with every new user.
  • Something set up on every request instead of once. For example, a new database connection or a new event listener for every page view.
  • Code that keeps a reference to a finished request. A timer or background task that holds on to request data long after the page was sent.
  • Pages that load far too much data. Not a leak exactly, but the symptom looks the same: a page that pulls thousands of rows can spike memory when a few people open it at once.

The first one also has a security side. If user-specific data is stored in shared memory, one user can end up seeing another user's data. That is worth checking even if memory is not a problem.

What to do about it

  1. Confirm it is really a leak. Memory going up is normal. Memory that never comes back down is the problem.
  2. Find what is growing. Developers can take snapshots of the server's memory and compare them to see what keeps accumulating.
  3. Fix the cause, not the symptom. A scheduled restart buys time. It does not solve anything.

When to ask for help

If the leak only appears under real production traffic, or the team has been relying on restarts for a long time, it can be worth getting a second pair of eyes on it.

I worked on a similar problem as part of a team — you can read about it in the SSR marketplace case study. Memory problems often come together with other production-only issues, such as hydration errors.

If this sounds like your app, a Production Health Audit is a low-risk way to start: I review the code and send you a written list of what I found and how to fix it.