redux-toolkit: Memory leak during SSR RTK request after upgrading from 1.9.5 -> ^1.9.6

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

About this issue

  • Original URL
  • State: open
  • Created 6 months ago
  • Comments: 19 (7 by maintainers)

Most upvoted comments

Thanks for looking into this. I just wanted to notify you that we went through the same process and also identified https://github.com/reduxjs/redux-toolkit/issues/3716 as the root-cause of a memory leak. Patching it back to the original code resulted in the disappearance of the leak.

@phryneas Could I ask where I should call store.dispatch(api.util.resetApiState()) in a NextJS page? FYI, I am using RTK Query and next-redux-wrapper for SSR. Here is what in my getServerSideProps:

export const getServerSideProps = wrapper.getServerSideProps(
  (store) => async (context) => {

    const res = await store.dispatch(
      getData.initiate({
        ...params,
      })
    );

    if (res.status === QueryStatus.fulfilled) {
      await Promise.all(store.dispatch(getRunningQueriesThunk()));
      return {
        props: {},
      };
    }

    return {
      notFound: true,
    };
  }
);

Hoping for a quick response πŸ˜„ Many thanks!

It’s ok πŸ˜ƒ Happy belated new year! Just clarified for myself. Yes, local patching is not a problem for me. May be I will try to offer some global solution, but I’m not sure in my skills πŸ˜ƒ Thanks for your afforts!

Hi! So, I have found a problematic commit: https://github.com/reduxjs/redux-toolkit/issues/3716 (56ac6133c94fb71f259eaeee912410defc16f24b)

Before this commit - no memory leak After - memory leaks

Change from:

    const request = new Request(url, config)
    const requestClone = request.clone()

to

    const request = new Request(url, config)
    const requestClone = new Request(url, config)

I think, object (or part of it) from the second new Request stays in memory and request.clone() works differently.

I took v2.0.1, changed this line back, built package and tested in my case and there was no memory leak on my server.

This commit, as I understand, fixed some bug in Chromium but leads to memory leak. So, I do not know what is better for you, but I hope you can fix both issues.

Thanks!

No problem, will do it ASAP. Thanks!