Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Question] SSR + Apollo Client instances #9520

Closed
joaobarbosaap opened this issue Mar 14, 2022 · 5 comments
Closed

[Question] SSR + Apollo Client instances #9520

joaobarbosaap opened this issue Mar 14, 2022 · 5 comments

Comments

@joaobarbosaap
Copy link

joaobarbosaap commented Mar 14, 2022

I have a production project running and we've detected some memory leaks around it, checking here on the issues I was able to see couple people talking about the same problem.

On my side I have a SSR project running with NextJS and a function called "createApolloClient" which is creating an ApolloClient instance on every request, we create a new cache (inMemoryCache), new apollo links and a new instance for each request that we receive on our pages. When we run it with node inspect I saw the memory leak quickly growing and checking the heap I saw a lot of apollo client calls and a bunch of arrays coming from apollo too. As my next step, I just removed the function call and just exported a single apollo client for every request, so doesn't matter how many requests we receive, I'm running just a single apollo client. This change just killed our memory leak.

To make sure that it was really on apollo, I applied the same pattern (function call creating an instance on every request) using urql and I didn't saw the memory leak happening.

My question is, my app doesn't have any user data related between requests to apollo, I only use it to fetch data from backend and serve to the user, doesn't matter which user is, how necessary is for me to create an apollo instance on every request? What is the problem with this approach?

@benjamn
Copy link
Member

benjamn commented Mar 14, 2022

My question is, my app doesn't have any user data related between requests to apollo, I only use it to fetch data from backend and serve to the user, doesn't matter which user is, how necessary is for me to create an apollo instance on every request? What is the problem with this approach?

Under those constraints, I agree it should be safe to reuse a single client/cache per server process!

The general advice we give in the docs about creating a new client for each request is somewhat simplistic/paranoid, but it prevents mixing different users' data (not a problem for you), and also avoids any issues around concurrently accessing the same client/cache from different request threads (less of a problem in single-threaded languages, but still something to consider with async request handling). The cost of that simplicity is the total loss of caching benefits across requests / over time, so it's definitely tempting to reuse the same client for multiple requests, if you safely can.

Although I think you can keep using the same client instance, you might want to trigger a periodic client.clearStore() to prevent unbounded (normal) cache memory accumulation (or at least client.cache.gc()). If concurrent access is a problem, you could maybe try recycling a small pool of clients, giving each request access to only one client at a time, while still allowing multiple simultaneous/overlapping requests.

I'm curious if you have any way to tell from your heap snapshots what's responsible for keeping old client data/resources alive after garbage collection. Also, what version of @apollo/client are you currently using?

@joaobarbosaap
Copy link
Author

@benjamn we're using ^3.4.17
After several tests we managed to solve by disabling the cache over the queries, so the multiple clients was not the issue, but some kind of saving cache was increasing every time.
One question that we have is if by having just a single client if we will end up into some slowness due so many requests being made through a single client, do you know if this can be an issue?

@jpvajda jpvajda added the 🏓 awaiting-team-response requires input from the apollo team label May 25, 2022
@jpvajda jpvajda added ⁉️ question and removed 🏓 awaiting-team-response requires input from the apollo team labels Sep 21, 2022
@phryneas
Copy link
Member

phryneas commented Feb 6, 2024

We have recently released Apollo 3.9 which I believe should have fixed the memory leak you were seeing here - so I'm going to close this.

If this issue keeps persisting in Apollo Client >= 3.9.0, please open a new issue!

@phryneas phryneas closed this as completed Feb 6, 2024
Copy link
Contributor

github-actions bot commented Feb 6, 2024

Do you have any feedback for the maintainers? Please tell us by taking a one-minute survey. Your responses will help us understand Apollo Client usage and allow us to serve you better.

Copy link
Contributor

github-actions bot commented Mar 9, 2024

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.
For general questions, we recommend using StackOverflow or our discord server.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Mar 9, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants