<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: xabierlameiro.com</title>
    <description>The latest articles on DEV Community by xabierlameiro.com (@xabierlameiro).</description>
    <link>https://dev.to/xabierlameiro</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1011356%2F478e63c7-639e-4917-9df5-3768dbc8c96c.jpeg</url>
      <title>DEV Community: xabierlameiro.com</title>
      <link>https://dev.to/xabierlameiro</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/xabierlameiro"/>
    <language>en</language>
    <item>
      <title>How to find a Next.js memory leak in production</title>
      <dc:creator>xabierlameiro.com</dc:creator>
      <pubDate>Sat, 18 Jul 2026 01:58:24 +0000</pubDate>
      <link>https://dev.to/xabierlameiro/how-to-find-a-nextjs-memory-leak-in-production-2cjd</link>
      <guid>https://dev.to/xabierlameiro/how-to-find-a-nextjs-memory-leak-in-production-2cjd</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://xabierlameiro.com/blog/nextjs/nextjs-memory-leak-in-production" rel="noopener noreferrer"&gt;xabierlameiro.com&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;If your self-hosted Next.js server grows until it dies with &lt;code&gt;FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memory&lt;/code&gt; - or the container gets &lt;code&gt;OOMKilled&lt;/code&gt; (exit code 137) - don't start by auditing your own code. As of July 2026 there are three documented memory leaks &lt;strong&gt;open in the framework itself&lt;/strong&gt;, spanning Next.js 15.5 to 16.3.&lt;/p&gt;

&lt;h2&gt;
  
  
  Leak 1: the router LRU cache doesn't count its keys
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/vercel/next.js/issues/94890" rel="noopener noreferrer"&gt;#94890&lt;/a&gt; - the route-resolution cache's size function adds up the value strings but never the URL key, so it can retain ~1M keys (hundreds of MB) while believing it is tiny. Signature: slow heap drift over days that tracks &lt;strong&gt;unique URLs served&lt;/strong&gt; (bot crawls, long slugs), not request volume; heap-snapshot retainer traces end at &lt;code&gt;LRUNode&lt;/code&gt;. Tip: chart your heap against distinct routes, not requests per second.&lt;/p&gt;

&lt;h2&gt;
  
  
  Leak 2: the RSC render tree is retained on client aborts
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/vercel/next.js/issues/94919" rel="noopener noreferrer"&gt;#94919&lt;/a&gt; - streams that don't finish normally (mobile clients, crawlers, users navigating away) pin the whole element tree via the Flight request's AbortController. Much stronger on Node 22/24 than 20; the reporter measured ~2 MB per request on heavy pages. Mitigation while it stays open: trim the RSC payload of your heaviest pages.&lt;/p&gt;

&lt;h2&gt;
  
  
  Leak 3: middleware setTimeout ids retained by the sandbox
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/vercel/next.js/issues/95094" rel="noopener noreferrer"&gt;#95094&lt;/a&gt; - the sandbox TimeoutsManager only releases a timeout id on explicit &lt;code&gt;clearTimeout&lt;/code&gt;. A one-line workaround that works today:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;timeoutId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;fireAndForgetWork&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nf"&gt;clearTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;timeoutId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// releases the id from the sandbox manager&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Which one are you hitting?
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Growth shape&lt;/th&gt;
&lt;th&gt;Correlates with&lt;/th&gt;
&lt;th&gt;Suspect&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Slow, monotonic drift over days&lt;/td&gt;
&lt;td&gt;Unique URLs (bots, long slugs)&lt;/td&gt;
&lt;td&gt;Router LRU cache (#94890)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Proportional to traffic; worse on heavy pages&lt;/td&gt;
&lt;td&gt;RSC payload and client aborts&lt;/td&gt;
&lt;td&gt;RSC tree retention (#94919)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Steps the GC never recovers&lt;/td&gt;
&lt;td&gt;Requests through middleware&lt;/td&gt;
&lt;td&gt;Sandbox timeouts (#95094)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;No OOM, but sporadic 504s on serverless&lt;/td&gt;
&lt;td&gt;Render cost, not memory&lt;/td&gt;
&lt;td&gt;Your render is expensive&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;To confirm: start with &lt;code&gt;NODE_OPTIONS='--inspect' next start&lt;/code&gt;, take two heap snapshots separated by load, and read the retainers in Chrome DevTools' Memory tab.&lt;/p&gt;

&lt;h2&gt;
  
  
  On serverless the leak wears a disguise
&lt;/h2&gt;

&lt;p&gt;You don't get the OOM - you get 504s. My blog's tag pages were timing out with &lt;code&gt;FUNCTION_INVOCATION_TIMEOUT&lt;/code&gt; because of an O(N^2) post loader (a ~32-second render against a ~10-second limit); instance recycling had been hiding the waste. The fix was a module-level cache: memory spent on purpose, bounded and static per deploy.&lt;/p&gt;

&lt;p&gt;The full diagnosis flow - which retainer maps to which issue, the exact docs commands, and my 504 postmortem with before/after numbers - is in the original post: &lt;a href="https://xabierlameiro.com/blog/nextjs/nextjs-memory-leak-in-production" rel="noopener noreferrer"&gt;https://xabierlameiro.com/blog/nextjs/nextjs-memory-leak-in-production&lt;/a&gt;&lt;/p&gt;

</description>
      <category>nextjs</category>
      <category>react</category>
      <category>node</category>
      <category>webdev</category>
    </item>
    <item>
      <title>How document my react components with JSDoc</title>
      <dc:creator>xabierlameiro.com</dc:creator>
      <pubDate>Thu, 19 Jan 2023 18:55:44 +0000</pubDate>
      <link>https://dev.to/xabierlameiro/how-document-my-react-components-with-jsdoc-2gnk</link>
      <guid>https://dev.to/xabierlameiro/how-document-my-react-components-with-jsdoc-2gnk</guid>
      <description>&lt;p&gt;It is necessary to have a good documentation about our components, so that other developers can understand how it works and how to use it. In this article we are going to see how we can document our react components with JSDoc and how to publish the documentation in our static site.&lt;/p&gt;

&lt;p&gt;With a few simple steps, the jsdoc library and the use of good programming practices when working with react, we will be able to have a documentation of our components automatically. There are different plugins to upgrade our jsdoc and support react, but as React is still javascript and the components functions the default lib is more than enough.&lt;/p&gt;

&lt;p&gt;The report we are going to generate is still an html file, so you can deploy it in any static site&lt;/p&gt;

&lt;p&gt;More details here : &lt;a href="https://xabierlameiro.com/blog/react/how-document-my-react-components-with-jsdoc"&gt;How document my react components with JSDoc&lt;/a&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>jsdoc</category>
      <category>nextjs</category>
    </item>
  </channel>
</rss>
