# Apollo Client cache not feasible for large data sets?

**URL:** <https://community.apollographql.com/t/apollo-client-cache-not-feasible-for-large-data-sets/8104>\
**Category:** Client SDKs\
**Tags:** client, web\
**Created:** [January 16, 2025, 2:20pm UTC](https://community.apollographql.com/t/apollo-client-cache-not-feasible-for-large-data-sets/8104 "2025-01-16T14:20:53Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![jhgrund](https://avatars.discourse-cdn.com/v4/letter/j/cc9497/32.png) [@jhgrund](https://community.apollographql.com/u/jhgrund)\
**Post date:** [January 16, 2025, 2:20pm UTC](https://community.apollographql.com/t/apollo-client-cache-not-feasible-for-large-data-sets/8104/1 "2025-01-16T14:20:53Z")

</div>

Hey 🙂

We’re using Apollo Client, and are in general satisfied. However, we’ve run into performance issues for some of our clients that have very large accounts, which leads to some large requests and store caches.

The UI will stutter and drop frames to a varying degree, but it’s very noticeable. It seems to increase/occur whenever a request comes in and tries to update the cache.

Based on discussion here: [Slow updates with large cache](https://community.apollographql.com/t/slow-updates-with-large-cache/7356)

we’ve looked into our cache sizes and limits, and have adjusted accordingly.

We seem to have a pretty large cache, but have adjusted the limits to accommodate it:

```auto
{
    "limits": {
        "parser": 1000,
        "canonicalStringify": 1000,
        "print": 2000,
        "documentTransform.cache": 2000,
        "queryManager.getDocumentInfo": 2000,
        "PersistedQueryLink.persistedQueryHashes": 2000,
        "fragmentRegistry.transform": 2000,
        "fragmentRegistry.lookup": 1000,
        "fragmentRegistry.findFragmentSpreads": 4000,
        "cache.fragmentQueryDocuments": 1000,
        "removeTypenameFromVariables.getVariableDefinitions": 2000,
        "inMemoryCache.maybeBroadcastWatch": 5000,
        "inMemoryCache.executeSelectionSet": 250000,
        "inMemoryCache.executeSubSelectedArray": 150000
    },
    "sizes": {
        "print": 26,
        "parser": 38,
        "canonicalStringify": 15,
        "links": [],
        "queryManager": {
            "getDocumentInfo": 27,
            "documentTransforms": []
        },
        "cache": {
            "fragmentQueryDocuments": 0
        },
        "addTypenameDocumentTransform": [
            {
                "cache": 27
            }
        ],
        "inMemoryCache": {
            "executeSelectionSet": 128121,
            "executeSubSelectedArray": 92948,
            "maybeBroadcastWatch": 49
        },
        "fragmentRegistry": {}
    }
}

```

It should be normalized, at least to a very high degree. We also have lint rules to ensure that everywhere an ID field is available, it is included in the query fragment on that type.

Any advice on how we can improve performance for the client/cache while managing large data sets would be much appreciated.

Thanks!

---

<div class="post-metadata">

**Author:** ![jerelmiller](https://sea1.discourse-cdn.com/flex019/user_avatar/community.apollographql.com/jerelmiller/32/3314_2.png) [@jerelmiller](https://community.apollographql.com/u/jerelmiller)\
**Post date:** [January 16, 2025, 3:41pm UTC](https://community.apollographql.com/t/apollo-client-cache-not-feasible-for-large-data-sets/8104/2 "2025-01-16T15:41:41Z")

</div>

Hey @jhgrund 👋

Have you taken any performance profiles to see where the the time is spent? Its difficult to recommend anything without knowing where the bottleneck is.

---

<div class="post-metadata">

**Author:** ![jhgrund](https://avatars.discourse-cdn.com/v4/letter/j/cc9497/32.png) [@jhgrund](https://community.apollographql.com/u/jhgrund)\
**Post date:** [January 17, 2025, 10:25am UTC](https://community.apollographql.com/t/apollo-client-cache-not-feasible-for-large-data-sets/8104/3 "2025-01-17T10:25:12Z")

</div>

Sure, I just found it very hard to get anything useful out of except a lot of store operations and recomputes.

There’s a bunch of long running tasks of many seconds in the profile, and they are so deeply nested a screenshot doesn’t do it justice.

Here’s a short video from one of the 4 second long running tasks from a profile:

[![Google Photos](https://us1.discourse-cdn.com/flex019/uploads/apollographql/original/2X/2/235ba75edd6c059735348800222c246ee4f1f8a3.gif "New item by Jesper Halborg") ](https://photos.app.goo.gl/YzhVzuyJWV3c7TBQ8)

---

<div class="post-metadata">

**Author:** ![jhgrund](https://avatars.discourse-cdn.com/v4/letter/j/cc9497/32.png) [@jhgrund](https://community.apollographql.com/u/jhgrund)\
**Post date:** [January 23, 2025, 9:00am UTC](https://community.apollographql.com/t/apollo-client-cache-not-feasible-for-large-data-sets/8104/4 "2025-01-23T09:00:40Z")

</div>

Here’s a screenshot from another perf slice:

 ![image](https://us1.discourse-cdn.com/flex019/uploads/apollographql/original/2X/4/4df48497a58e7c536acb159d770ab6c94dcac84f.jpeg)

The store seems to go into a loop or something somehow, causing the entire page to hang. Is that a symptom of something we do wrong somewhere?

It can only be reproduced for our clients with large hierarchies

The request that kicks off the most recalculations from the store is a very simple one

```graphql
export const LATEST_TIMESTAMP_QUERY = gql(/* GraphQL */ `
  query LatestValueReceivedForInstallation($installationId: ID!) {
    node(id: $installationId) {
      ... on Installation {
        id
        name
        dataLastReceivedAt
      }
    }
  }
`);

```

It only receives id and string scalars on a single node, no nested types or anything.

---

<div class="post-metadata">

**Author:** ![lenz](https://sea1.discourse-cdn.com/flex019/user_avatar/community.apollographql.com/lenz/32/4007_2.png) [@lenz](https://community.apollographql.com/u/lenz)\
**Post date:** [January 23, 2025, 9:25am UTC](https://community.apollographql.com/t/apollo-client-cache-not-feasible-for-large-data-sets/8104/5 "2025-01-23T09:25:43Z")

</div>

Can you maybe send one of those profiles to [lenz@apollographql.com](mailto:lenz@apollographql.com) ? From just the screenshot it’s impossible to tell anything here.

---

<div class="post-metadata">

**Author:** ![jhgrund](https://avatars.discourse-cdn.com/v4/letter/j/cc9497/32.png) [@jhgrund](https://community.apollographql.com/u/jhgrund)\
**Post date:** [January 23, 2025, 9:34am UTC](https://community.apollographql.com/t/apollo-client-cache-not-feasible-for-large-data-sets/8104/6 "2025-01-23T09:34:56Z")

</div>

Would love to, but I can’t save them, chrome throws error saying

`Failed to save timeline: Invalid string length (RangeError)`

when I try to save the profile. Apparently, after some googling, it’s too large to save, even if I tried to make the profile short in length

I’ve tried screen recording the trace a bit for you here:

[![](https://us1.discourse-cdn.com/flex019/uploads/apollographql/original/2X/b/b0af3021fdbf86f0fe7d4677cacac8fddc722ec0.jpeg "Screen Recording 2025 01 23 at 10 25 03") ](https://www.youtube.com/watch?v=1xaezh-Z2n0)

---

<div class="post-metadata">

**Author:** ![jhgrund](https://avatars.discourse-cdn.com/v4/letter/j/cc9497/32.png) [@jhgrund](https://community.apollographql.com/u/jhgrund)\
**Post date:** [January 23, 2025, 9:35am UTC](https://community.apollographql.com/t/apollo-client-cache-not-feasible-for-large-data-sets/8104/7 "2025-01-23T09:35:28Z")

</div>

I’ve also found this (old) bug in the mean time, but can’t tell if it was ever solved or just auto closed?

> <https://github.com/apollographql/apollo-client/issues/7436>
>
> \*\*Intended outcome:\*\*
> I have a component that retrieves some data using useQuer…y and renders a chart. Until now I used these options:
> \`\`\`
> fetchPolicy: 'cache-and-network',
> nextFetchPolicy: 'cache-first'
> \`\`\`
> But now I realized that I have some data that may change and I need it to be up-to-date. I still want to use the cache, so I think that \*\*cache-and-network\*\* fetchPolicy would be the best in this case.
> 
> \*\*Actual outcome:\*\*
> When I change the fetchPolicy to \*\*cache-and-network\*\* or \*\*network-only\*\* I end up having an infinite loop. This doesn't happen when I use \*\*no-cache\*\*.
> 
> This is how the component looks like:
> 
> \`\`\`
> export const GET\_CHART\_DATA = gql\`
> query getChartData(
> $year: Int!
> $previousYear: Int!
> $currentYearStartDate: Date
> $currentYearEndDate: Date
> $previousYearStartDate: Date
> $previousYearEndDate: Date
> $product: String
> $channel: String
> ) {
> currentYearData: reportings(
> year: $year
> service: "OTHERS"
> date\_Gte: $currentYearStartDate
> date\_Lte: $currentYearEndDate
> productType\_In: $product
> channelType\_In: $channel
> dateType: "VISITS"
> ) {
> edges {
> node {
> date
> value
> }
> }
> }
> 
> previousYearData: reportings(
> year: $previousYear
> service: "OTHERS"
> date\_Gte: $previousYearStartDate
> date\_Lte: $previousYearEndDate
> productType\_In: $product
> channelType\_In: $channel
> dateType: "VISITS"
> ) {
> edges {
> node {
> date
> value
> }
> }
> }
> 
> budgetData(
> year: $year
> type: "OTHERS"
> date\_Gte: $currentYearStartDate
> date\_Lte: $currentYearEndDate
> ) {
> edges {
> node {
> date
> value
> }
> }
> }
> }
> \`;
> 
> const ChartContainer = ({ dateRangeVariables, filters }) =\> {
> const { loading, data, error } = useQuery(GET\_CHART\_DATA, {
> variables: {
> ...dateRangeVariables,
> product: filters.product.map(({ value }) =\> value).join(','),
> channel: filters.channel.map(({ value }) =\> value).join(',')
> },
> fetchPolicy: 'cache-and-network'
> });
> 
> if (loading) {
> return \<div\>Loading\</div\>;
> }
> 
> if (error) {
> return \<div\>Error\</div\>;
> }
> 
> // structure data for chart...
> 
> return \<div\>Chart\</div\>;
> };
> \`\`\`
> 
> \*\*Versions\*\*
> @apollo/client 3.2.0
> 
> I assume this is a cache issue, but I'm not sure if it's my fault or not and I don't know how to fix it.
> Any ideas?
> 
> Thank you for your time!
> 
> 
> 
> \*\*Edit\*\*: I also think that defaultOptions is not working correctly. I have these options set when I create the apollo client instance:
> \`\`\`
> defaultOptions: {
> query: {
> fetchPolicy: 'cache-and-network',
> nextFetchPolicy: 'cache-first'
> }
> }
> \`\`\`
> First time when I render a component that queries some data I see the network request. If I switch to another view and then come back, I see no request (it's retrieved from the cache - \*\*cache-first?\*\*). Anyway, if I use \*\*fetchPolicy: 'cache-and-network'\*\* option inside useQuery I always see the request at component mount. Is this the expected behavior ?

The simple query I linked uses `fetchPolicy: 'cache-and-network'` and we’re using `"@apollo/client": "3.12.2"`

---

<div class="post-metadata">

**Author:** ![jhgrund](https://avatars.discourse-cdn.com/v4/letter/j/cc9497/32.png) [@jhgrund](https://community.apollographql.com/u/jhgrund)\
**Post date:** [January 23, 2025, 9:39am UTC](https://community.apollographql.com/t/apollo-client-cache-not-feasible-for-large-data-sets/8104/8 "2025-01-23T09:39:34Z")

</div>

Memory also climbs throughout the trace

 ![image](https://us1.discourse-cdn.com/flex019/uploads/apollographql/original/2X/3/38d5157424b507bbf401050a5045455617876395.png)

---

<div class="post-metadata">

**Author:** ![lenz](https://sea1.discourse-cdn.com/flex019/user_avatar/community.apollographql.com/lenz/32/4007_2.png) [@lenz](https://community.apollographql.com/u/lenz)\
**Post date:** [January 23, 2025, 10:28am UTC](https://community.apollographql.com/t/apollo-client-cache-not-feasible-for-large-data-sets/8104/9 "2025-01-23T10:28:22Z")

</div>

That issue was related to memoization cache sizes, and while I agree that your problem here _looks_ like it would hit a memoization cache limit, in your initial post you show a level of usage that doesn’t.

Maybe you can try to profile with Firefox instead or record a [replay.io](http://replay.io) replay?  
I really can’t read anything for half of that video and would need to look around in that data myself.

---

<div class="post-metadata">

**Author:** ![jhgrund](https://avatars.discourse-cdn.com/v4/letter/j/cc9497/32.png) [@jhgrund](https://community.apollographql.com/u/jhgrund)\
**Post date:** [January 23, 2025, 2:15pm UTC](https://community.apollographql.com/t/apollo-client-cache-not-feasible-for-large-data-sets/8104/10 "2025-01-23T14:15:42Z")

</div>

Sent you a performance profile from Firefox 👍

---

<div class="post-metadata">

**Author:** ![lenz](https://sea1.discourse-cdn.com/flex019/user_avatar/community.apollographql.com/lenz/32/4007_2.png) [@lenz](https://community.apollographql.com/u/lenz)\
**Post date:** [January 23, 2025, 2:23pm UTC](https://community.apollographql.com/t/apollo-client-cache-not-feasible-for-large-data-sets/8104/11 "2025-01-23T14:23:10Z")

</div>

Hmm. This solidifies my gut feeling that you might be hitting memoization cache limits.

Which gives me an idea: `getMemoryInternals` only shows the limits that would be in place if the cache would be created now - but not necessarily the limits that were in place when the cache was created. Could it be that you set these limits too late and they don’t get picked up?
