#NextJS Memory Leak

37 messages · Page 1 of 1 (latest)

copper leaf
#

Hello!

I have a NextJS Project that uses websockets. I have deployed to Railway successfully, but am concerned about the memory usages of the server. For those who are not aware railway deploys code and you rent a server for the whole month rather than vercel architecture where you pay for the time that you use on your server. Since I am using websockets and need the connections to persist for a long time, I chose to go this route.

The problem is this. After deploying a change to the website the server load is around 200mb. Then when a user connects to the website the server load suddenly jumps up to around 400-500mbs. Even though this is quite a significant load, I am not worried about this spike.

The issue that I am worried about is that this spike seems to persist even if that user ceases to use the website. So that 400mbs-500mbs will stay with the server until after another deployment. It is constantly using resources and I am not quite sure why.

I have stress tested my website with multiple clients open all sending messages and the server spiked to 1.5GB of memory usage which would not fall down even after all clients disconnected.

Here is a list of the things that I have tried to fix this issue:

  1. Used export const dynamic = 'force-dynamic' in order to stop caching of data inside of the server in case this was a problem.
    Reasoning: I thought that the server would cache the html from the website into the server and serve it to the client, in order to prevent this i disabled caching in the routes with the most html.

  2. Disabled Polling Inside Of My Website
    Reasoning: My project Uses Websockets, and when a socket is not connected it reverts to polling. I figured that this setup could be persistently calling the server and putting on a load.

  3. Checked logs To See if Sockets are disconnecting correctly (They Are)

  4. https://github.com/vercel/next.js/issues/49929
    I have also checked this github issues post. However most of the comments seem to suggest that the issue is with the appdir. I am using the app directory structure in my application, and cannot turn off the appdir like some in this thread are saying to do as a solution.

I believe that there is some sort of memory leak happening, since the memory usage is constantly slowly creeping upwards. If there are tools that anyone knows about that check for memory leaks, or if there are common patterns that I should look out for. Please let me know!

I am also willing to completly start over with this project if that is needed. This is my first nextjs project and I would like to understand what I need to do to prevent memory leaks. I have started the process of finding the leak by having every route returning null so that none of my code is being run. However I am slightly worried since the memory usage on the server is still slowly creeping up from 350mb to 400mb without any usage in the course of a day.

GitHub

Verify canary release I verified that the issue exists in the latest Next.js canary release Provide environment information Operating System: Platform: darwin Arch: arm64 Version: Darwin Kernel Ver...

noble badgeBOT
#

🔎 This post has been indexed in our web forum and will be seen by search engines so other users can find it outside Discord

🕵️ Your user profile is private by default and won't be visible to users outside Discord, if you want to be visible in the web forum you can add the "Public Profile" role in id:customize

✅ You can mark a message as the answer for your post with Right click -> Apps -> Mark Solution
(if you don't see the option, try refreshing Discord with Ctrl + R)

copper leaf
#

I realize that nextjs is a serverless architecture, and that sockets require a server to be constantly running. So this may not be the best combination, however I believe that services such as chatgpt use websockets and were using nextjs as well. Are these memory leaks just a fundamental incompatibility between the two services? If so, is there another commonly reccomended framework that has the server action functionality that nextjs has that I could use?

copper leaf
#

Update:
I have tried having the routes like start/example layout.tsx fetch the data that I need. Then return null as its component/html instead of the components that I have rendered before that used my data. Now opening 50 tabs of the website will spike the usage by 50mb, then when I close the tabs the server memory will decrease again to baseline. This is exactly the behavior that I want, before when I was rendering client components instead of null. The usage of the server will spike and then never go back down when I close the tabs. I hope this extra context helps!

fair stream
#

websockets with nextjs is not a good idea

#

you should move that to a external node server

copper leaf
#

Yes it is starting to look that way with this memory usage error. However I just have one quick question about how data is passed from server to client in nextjs

#

import { ReactNode } from 'react';
import fetchCoursesAndServers from '../../server_actions/fetchCoursesAndServers';
import StudentSearch from '../../(site)/components/StudentSearch';
import fetchAllProfiles from '../../server_actions/fetchAllProfiles';
import fetchHighSchoolNames from '../../server_actions/fetchHighSchoolNames';

export const dynamic = 'force-dynamic';

export default async function Layout({children}:{children:ReactNode}) {
    const courses = await fetchCoursesAndServers();
    const students = await fetchAllProfiles();
    const highSchools = await fetchHighSchoolNames();

    const courseNames = courses.map((course) => course.abbreviation + " " + course.course_number);

    return null;
    
    return (
        <div
            style={{
              width: '100%',
              height: '100%',
              backgroundColor: 'var(--color-background)',
              display: "flex",
              justifyContent:'space-between',
              borderRadius: '5px',
            }}
        >

            <StudentSearch highSchools={highSchools} courses={courseNames} students={students}/>
            
            {children}
        </div>
    );
}

#

I have been testing this route, and it seems that when I return null instead of this studentSearch client component, that the memory usage errors stop. The garbage collection will take all unused data and then clean up after itself. However, the memory usage will never clean up after I use a client component and instead of return null return studentSearch.

#

Is this data fetching on server and giving to a client component that uses "use client" wrong?

fair stream
#

no

#

but that has nothing to do with nextjs, u should check your functions and your StudentSearch component

#

memory usage where btw?

#

on the server or client

copper leaf
#

server

fair stream
#

yeah check your rsc functions

copper leaf
#

quick question what is an rsc?

fair stream
#

react server component

#

everything without "use client"

copper leaf
#

ahh makes sense

#

but should a client component affect the server memory and cause that memory build up?

#

I am thinking that the inital rendering of the client component happens on server and sends to cleint, but in the server the unused data is never being picked up by garbage collection. However I am not using many server components, my pattern is mostly using things like layout.tsx to fetch data and then feeding it to a client component.

I checked my server actions and simply using them does not keep the memory usage high on the server. It is only when I render a client component that uses that data from the server actions

fair stream
copper leaf
#

yes. the memory usage will spike when the tabs are opened since its fetching the data, then it drops to normal after cleaned up. But rendering the StudentSearch will stop this behavior

#

its basically a filtering program. Takes in a group of people and filtres them based on certain attributes that you fill in the form

#

I am using Virtuoso in the FilteredStudentList component. Testing commenting out that part to test for any memory leaks in that library

copper leaf
#

I think that I may have solved the problem? The client component that I was using StudentSearch was using FilteredStudentList which didint declare "use client" on the top. So I think it was a server component that the server never collected. So all of those people in the website were being cached and rendered on the server and never collected leading to massive memory build up.

Does this reasoning make sense? Just trying to understand NextJS a little more, on the bright side memory usage is being cleaned up again so yay!

noble badgeBOT
#
✅ Success!

This question has been marked as answered! If you have any other questions, feel free to create another post

Jump to answer
copper leaf
#

Thanks for your time! You reminding me of server components and looking into it reminded me that you cant put server components inside of client components!

fair stream
#

and basically render your server component from the client

#

the initial render will be still on the server tho

copper leaf
#

but the initial render will be garbage collected after the client component renders the server component inside of it and stop taking up memory on server right?