apollo-client: Apollo Client + NextJS, getServerSideProps memory leak, InMemoryCache

Official 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(),
        },
    };
}

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Reactions: 13
  • Comments: 18 (8 by maintainers)

Most upvoted 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!

@joekur we just shipped RC.1, and if nothing else comes up I would guess about a week.

Hey everyone! We released the beta containing our memory story this week - you can read all about it in the announcement blog post.

We would be very grateful if you could try it out and report us your cache measurements so we can dial in the right default cache limits (more details in the blogpost) 😃

@jerelmiller was just giving that a look. Gave it a local test, and it does indeed look to fix the issue. Nice work! 👏

Awesome thanks for the update and for all the movement happening on the project!!