Apollo Client + NextJS, getServerSideProps memory leak, InMemoryCache
See original GitHub issueOfficial Apollo and NextJS recommendations are about to create a new ApolloClient instance each time when the GraphQL request should be executed in case if SSR is used.
This shows good results by memory usage, memory grows for some amount and then resets with the garbage collector to the initial level.
The problem is that the initial memory usage level constantly grows and the debugger shows that leaking is caused by the “InMemoryCache” object that is attached to the ApolloClient instance as cache storage.
We tried to use the same “InMemoryCache” instance for the all new Apollo instances and tried to disable caching customizing policies in “defaultOptions”, but the leak is still present.
Is it possible to turn off cache completely? Something like setting a “false” value for the “cache” option in ApolloClient initialization? Or maybe it’s a known problem with a known solution and could be solved with customization of the “InMemoryCache”?
We tried numerous options, such as force cache garbage collection, eviction of the objects in the cache, etc., but nothing helped, the leak is still here.
Thank you!
export function createApolloClient(apolloCache) {
return new ApolloClient({
cache: apolloCache,
connectToDevTools: !!isBrowser,
link: ApolloLink.from([
errorLink,
authLink,
createUploadLink({ credentials: "include", uri }),
]),
ssrMode: !isBrowser,
typeDefs,
resolvers,
defaultOptions: {
watchQuery: {
fetchPolicy: "cache-first",
errorPolicy: "all",
},
query: {
fetchPolicy: "cache-first",
errorPolicy: "all",
},
},
});
}
export function initializeApollo(initialState = {}) {
const _apolloCache = apolloCache || createApolloCache();
if (!apolloCache) apolloCache = _apolloCache;
// console.log("APOLLO_CACHE", apolloCache);
// apolloCache.evict();
apolloCache.gc();
const _apolloClient = apolloClient || createApolloClient(_apolloCache);
// For SSG and SSR always create a new Apollo Client
if (typeof window === "undefined") return _apolloClient;
// Create the Apollo Client once in the client
if (!apolloClient) apolloClient = _apolloClient;
return _apolloClient;
}
export function useApollo(initialState) {
const store = useMemo(() => initializeApollo(initialState), [initialState]);
return store;
}
On page
export async function getServerSideProps(context) {
const apolloClient = initializeApollo();
const biteId =
(context.query && context.query.id) ||
(context.params && context.params.id);
const realId = delQuery(biteId);
try {
await apolloClient.query({
query: FETCH_BLERP,
variables: { _id: realId },
ssr: true,
});
} catch (err) {
console.log("Failed to fetch blerp");
}
return {
props: {
_id: realId,
initialApolloState: apolloClient.cache.extract(),
},
};
}
Issue Analytics
- State:
- Created a year ago
- Reactions:9
- Comments:6 (1 by maintainers)
Top GitHub Comments
Hi all, we are taking a fresh look at server-side rendering for release 3.8. See https://github.com/apollographql/apollo-client/issues/10231 for more details and please feel free to provide feedback 🙏🏻 As we get into the implementation details we’ll have a better sense of how to tackle memory management in this new paradigm. Thanks for your patience!
Awesome thanks for the update and for all the movement happening on the project!!