-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Open
Labels
Description
Hello!
So, I'm using this approach for server side prefetching data:
https://redux-toolkit.js.org/rtk-query/usage/server-side-rendering#server-side-rendering-elsewhere
const createApi = buildCreateApi(
coreModule(),
reactHooksModule({ unstable__sideEffectsInRender: true })
)
....
store.dispatch(api.endpoints.getSomethingById.initiate(1))
await Promise.all(
store.dispatch(api.util.getRunningQueriesThunk())
)
preloadedState = { ...store.getState() }
Before upgrading to RTK v2 and Redux 5 this fills store with specific query and subscription:
api: {
queries: {
'getSomethingById(1)': {
status: 'fulfilled',
...
},
mutations: {},
provided: {},
subscriptions: {
'getSomethingById(1)': {
...
}
},
config: {
...
}
}
}
After upgrading it looks like:
api: {
queries: {
'getSomethingById(1)': {
status: 'fulfilled',
...
},
mutations: {},
provided: {},
subscriptions: {},
config: {
...
}
}
}
Subscription is empty.
Also, such server side prefetching leads now to memory leak - server memory consumption grows, however before upgrading there was no such problem on server.
Thanks
Metadata
Metadata
Assignees
Labels
Type
Projects
Milestone
Relationships
Development
Select code repository
Activity
[-]No subscription after initiate durung SSR after upagrading to v2/v5[/-][+]No subscription after initiate during SSR after upgrading to v2/v5[/+]phryneas commentedon Dec 17, 2023
I think you have a misconception of the term "subscription" here - the term "subscription" means "hey, something is still using that and you should definitely not clear it out of memory".
If you were rehydrating subscriptions created on the server in the browser, you would have subscriptions for component that could never signal "hey, I don't need this anymore" since they don't live in the browser - those would be held onto forever, and never be cache-collected.
That's why
extractRehydrationInfo
will never rehydrate subscriptions, but only query contents.As for a memory leak on the server: you are aware that you should create a new Redux store for every single server-side-render, and throw it away afterwards? No matter how many contents you have in that Redux store: as you dispose of the whole store, that should never cause any rise in memory usage.
With all that added knowledge, can you explain a little bit more what you are doing here and why you think you see an increase of memory usage because of subscriptions?
StopNGo commentedon Dec 17, 2023
Thanks for the answer!
You can check full code here:
https://github.com/StopNGo/react-proto/blob/main/src/server/middlewares/serverRenderer.tsx
Before RTK upgrade there was no memory leak on server.
After upgrade I noticed the memory leak. If I comment a line with data prefetching (
59: await apiRequest(store)
) the memory leak problem disappears.phryneas commentedon Dec 17, 2023
I don't really see you following the advice in our docs:
store.dispatch(api.util.resetApiState())
, which will cause lingering promises for a while (which would explain data leaking on the server - it will be cleaned up, but only after 60 seconds.extractRehydrationInfo
, which will lead to memory leaks in the browser if you accidentally move subscriptions over.StopNGo commentedon Dec 17, 2023
phryneas commentedon Dec 17, 2023
extractRehydrationInfo
has nothing to do with Next.js, you should use it with persistence or any other kind of (not only SSR) hydration as well, which you have to do with an action, not by usinginitialState
. (Also see persistence and rehydration).It does not change anything. Before upgrade without resetting api state there was no memory leak on server. After upgrade it is even if I reset api state.
If that is the case, it has probably nothing whatsoever to do with subscriptions. From what version are you updating, and if you take a heap snapshot, can you identify what exactly is leaking here?
StopNGo commentedon Dec 17, 2023
Here is server snapshot comparisons - before and after 1000 requests to server:

I am not so good in snapshot analyzing, so maybe I can not identify exact source of leaking, but, again:
Upgrade:
@reduxjs/toolkit: 1.9.3 -> 2.0.1
redux: 4.2.1 -> 5.0.0
phryneas commentedon Dec 17, 2023
Could you maybe switch to 1.9.7 so we see if this problem started occuring within the 1.9 line or with the 2.0 upgrade?
As for the snapshots - up where it says "summary" you should be able to select "compare" and then it shows you a diff between the two snapshots, what grew etc..
[-]No subscription after initiate during SSR after upgrading to v2/v5[/-][+]Memory leak during SSR RTK request after upgrading to v2/v5[/+]StopNGo commentedon Dec 17, 2023
So, yes, I have found, that with 1.9.7 memory also leaks.
If it is not too intrusive, can I send you snapshots for comparison? I afraid, that I can not do proper comparison.
StopNGo commentedon Dec 17, 2023
And leaking starts from 1.9.6:
1.9.5 - no memory leak
1.9.6 - memory leaks
[-]Memory leak during SSR RTK request after upgrading to v2/v5[/-][+]Memory leak during SSR RTK request after upgrading from 1.9.5 -> ^1.9.6[/+]phryneas commentedon Dec 17, 2023
I can't guarantee you that I can read anything from the snapshots, but please send them, maybe we get lucky :)
mail@lenzw.de
phryneas commentedon Dec 17, 2023
I just went over all code that changed in 1.9.6, and I can't see anything suspcious.
I know it's a lot, but could I ask you to
git bisect
for the change that caused the memory leak?StopNGo commentedon Dec 17, 2023
No problem, will do it ASAP.
Thanks!
16 remaining items