nextjs - ✅(Solved) Fix Null cache entries have size 0, preventing LRU eviction [1 pull requests, 1 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
vercel/next.js#89033Fetched 2026-04-08 02:03:28
View on GitHub
Comments
1
Participants
2
Timeline
10
Reactions
0
Author
Timeline (top)
labeled ×3cross-referenced ×2closed ×1commented ×1

Fix Action

Fixed

PR fix notes

PR #89040: fix: ensure LRU cache items have minimum size of 1 to prevent unbounded growth

Description (problem / solution / changelog)

What?

Prevent LRU cache unbounded growth by requiring calculateSize to return values > 0.

Why?

When calculateSize returned 0 (e.g., for null values in the filesystem route cache), items were never evicted because they didn't contribute to totalSize. This caused unbounded memory growth when handling dynamic routes like /api/logs/[id] where each unique ID created a new cache entry with size 0.

How?

  1. LRUCache now throws an error if size ≤ 0 - This catches bugs at development time rather than silently masking them:

    if (size <= 0) {
      throw new Error(
        \`LRUCache: calculateSize returned ${size}, but size must be > 0. \` +
        \`Items with size 0 would never be evicted, causing unbounded cache growth.\`
      )
    }
  2. Fixed filesystem.ts - Null entries (negative cache) now return size 1 instead of 0:

    if (!value) {
      // Null entries (negative cache) still need a non-zero size for LRU eviction
      return 1
    }
  3. Fixed next-dev-server.ts - Static paths cache now uses || 1 instead of ?? 0:

    return JSON.stringify(value.staticPaths)?.length || 1

Fixes #89033

Changed files

  • packages/next/errors.json (modified, +2/-1)
  • packages/next/src/server/dev/next-dev-server.ts (modified, +2/-1)
  • packages/next/src/server/lib/lru-cache.ts (modified, +6/-0)
  • packages/next/src/server/lib/router-utils/filesystem.ts (modified, +4/-1)

Code Example

Operating System:
  Platform: darwin
  Arch: arm64
  Version: Darwin Kernel Version 24.6.0: Mon Aug 11 21:16:31 PDT 2025; root:xnu-11417.140.69.701.11~1/RELEASE_ARM64_T6030
  Available memory (MB): 36864
  Available CPU cores: 11
Binaries:
  Node: 23.4.0
  npm: 10.9.2
  Yarn: 1.22.22
  pnpm: 9.12.3
Relevant Packages:
  next: 16.2.0-canary.8 // Latest available version is detected (16.2.0-canary.8).
  eslint-config-next: N/A
  react: 19.2.3
  react-dom: 19.2.3
  typescript: N/A
Next.js Config:
  output: N/A
RAW_BUFFERClick to expand / collapse

Link to the code that reproduces this issue

https://github.com/iMUngHee/nextjs-lru-memory-leak

To Reproduce

  1. npm install --ignore-scripts
  2. npm run build && npm start
  3. node test-memory-leak.mjs (sends 50k requests with unique IDs)
  4. Take heap snapshot of the server process
  5. Search for LRUNode - count matches request count

Current vs. Expected behavior

Current: LRUNode instances grow unbounded. Each unique dynamic route path creates a new entry that never gets evicted.

Expected: LRU cache should evict old entries when reaching maxSize (1MB).

Provide environment information

Operating System:
  Platform: darwin
  Arch: arm64
  Version: Darwin Kernel Version 24.6.0: Mon Aug 11 21:16:31 PDT 2025; root:xnu-11417.140.69.701.11~1/RELEASE_ARM64_T6030
  Available memory (MB): 36864
  Available CPU cores: 11
Binaries:
  Node: 23.4.0
  npm: 10.9.2
  Yarn: 1.22.22
  pnpm: 9.12.3
Relevant Packages:
  next: 16.2.0-canary.8 // Latest available version is detected (16.2.0-canary.8).
  eslint-config-next: N/A
  react: 19.2.3
  react-dom: 19.2.3
  typescript: N/A
Next.js Config:
  output: N/A

Which area(s) are affected? (Select all that apply)

Route Handlers, Performance

Which stage(s) are affected? (Select all that apply)

Other (Deployed), next start (local)

Additional context

I am running version 15.5.9 with self-hosting, and while investigating the cause of memory leaks, I discovered that LRUNode instances were accumulating abnormally in heap dumps.

extent analysis

TL;DR

The most likely fix is to implement a proper eviction mechanism for the LRU cache to prevent unbounded growth of LRUNode instances.

Guidance

  • Review the LRU cache implementation to ensure it correctly evicts old entries when reaching the maxSize limit (1MB).
  • Verify that the LRUNode instances are being properly removed from the cache when their corresponding dynamic route paths are no longer in use.
  • Investigate the nextjs-lru-memory-leak repository code to identify potential issues with the cache implementation.
  • Consider adding logging or monitoring to track the growth of LRUNode instances and cache size to detect potential memory leaks.

Example

No specific code snippet can be provided without modifying the original code, but a potential solution might involve implementing a cache eviction policy, such as removing the least recently used items when the cache reaches its maximum size.

Notes

The issue seems to be related to the LRU cache implementation in the nextjs-lru-memory-leak repository, and resolving it may require modifications to the cache code. The provided environment information and reproduction steps should help in debugging and identifying the root cause.

Recommendation

Apply workaround: Implement a custom cache eviction mechanism to prevent unbounded growth of LRUNode instances, as the current implementation seems to be flawed. This should help mitigate the memory leak issue until a proper fix is available.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING