Debugging OOMKilled errors and fixing memory leaks in serverless-like environments.
Source: Dev.to
You’ve just containerized your shiny Next.js application. You’ve set resource limits in Kubernetes (say, memory: 512Mi). Everything works fine locally. But in production, after a few hours—or sometimes under the first real load—your pod dies. kubectl describe pod shows the dreaded: text The short answer: Next.js is not a static binary. Under the hood, it caches aggressively, and Kubernetes enforces limits that Next.js was never designed to respect. Let’s break down why this happens and how to fix it. The 3 Memory Hogs in Next.js Most people think Next.js is just React on the server. But in standalone mode, it runs three distinct subsystems, each with its own memory profile. A) The Node.js Runtime (App Router & Pages Router) React Server Components (RSC) payloads are kept in memory longer than you think. Streaming responses hold buffers. B) The Built-in Cache System Data Cache: fetch() results with force-cache (infinite TTL by default). Full Route Cache: Rendered page payloads (for static/dynamic segments). Router Cache: Client-side (but that’s the browser). On the server, the Data Cache and Full Route Cache live in the Node.js heap. With many unique pages or cache keys, memory grows without bound. C) Incremental Static Regeneration (ISR) Result: In a Kubernetes pod with a 512Mi memory limit, your Next.js app may need 1Gi+ after a few hundred unique cache entries. Why K8s Makes It Worse Unlike a VM, Kubernetes doesn’t swap. It uses hard memory limits via cgroups. When Node.js tries to allocate more than the limit, the kernel’s OOM killer instantly terminates the process. Node.js has its own garbage collector (GC). It sees memory pressure and tries to free it—but here’s the catch: Node.js’s heap limit often ignores cgroup limits on older versions. Node.js 80% limit for 5 minutes. Final Checklist Before You Ship The Bottom Line Bridge the gap by explicitly managing that cache and correctly sizing the Node.js heap. Or move static pages to a CDN and keep only dynamic routes in the pod. Next.js on K8s works beautifully—once you stop treating it like a static file server. Further reading: Next.js Custom Cache Handler Kubernetes OOM Explained Node.js memory limits in containers Let’s discuss: Have you seen Next.js OOMKilled in production? What was your fix? 👇