From 1d25e75121e3025a24e72b6ccb4b5305d91de150 Mon Sep 17 00:00:00 2001 From: Jacob Ley Date: Wed, 9 Mar 2022 13:27:45 -0500 Subject: [PATCH 1/2] feat(cacheTime): default cacheTime to Infinity for SSR Cache persists for the lifecycle of request and can be immediately GCed afterward Helps close Node process immediately after use --- docs/src/pages/reference/useQuery.md | 2 +- src/core/query.ts | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/docs/src/pages/reference/useQuery.md b/docs/src/pages/reference/useQuery.md index 5731a20ab4..cd1a1e2915 100644 --- a/docs/src/pages/reference/useQuery.md +++ b/docs/src/pages/reference/useQuery.md @@ -97,7 +97,7 @@ const result = useQuery({ - The time in milliseconds after data is considered stale. This value only applies to the hook it is defined on. - If set to `Infinity`, the data will never be considered stale - `cacheTime: number | Infinity` - - Defaults to `5 * 60 * 1000` (5 minutes) + - Defaults to `5 * 60 * 1000` (5 minutes) or `Infinity` during SSR - The time in milliseconds that unused/inactive cache data remains in memory. When a query's cache becomes unused or inactive, that cache data will be garbage collected after this duration. When different cache times are specified, the longest one will be used. - If set to `Infinity`, will disable garbage collection - `queryKeyHashFn: (queryKey: QueryKey) => string` diff --git a/src/core/query.ts b/src/core/query.ts index 3ad311054a..4cd3f57645 100644 --- a/src/core/query.ts +++ b/src/core/query.ts @@ -2,6 +2,7 @@ import { getAbortController, Updater, functionalUpdate, + isServer, isValidTimeout, noop, replaceEqualDeep, @@ -187,10 +188,10 @@ export class Query< this.meta = options?.meta - // Default to 5 minutes if not cache time is set + // Default to 5 minutes (Infinity for server-side) if not cache time is set this.cacheTime = Math.max( this.cacheTime || 0, - this.options.cacheTime ?? 5 * 60 * 1000 + this.options.cacheTime ?? (isServer ? Infinity : 5 * 60 * 1000) ) } From aa9ba1dadb8d6a9d202d05dfdb806907a24bc7fa Mon Sep 17 00:00:00 2001 From: Jacob Ley Date: Thu, 24 Mar 2022 16:42:14 -0400 Subject: [PATCH 2/2] docs: Add default server-side cacheTime to migration docs --- docs/src/pages/guides/migrating-to-react-query-4.md | 10 +++++++++- docs/src/pages/guides/ssr.md | 4 +++- docs/src/pages/guides/testing.md | 2 +- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/docs/src/pages/guides/migrating-to-react-query-4.md b/docs/src/pages/guides/migrating-to-react-query-4.md index e106cba9c2..f718f4b69e 100644 --- a/docs/src/pages/guides/migrating-to-react-query-4.md +++ b/docs/src/pages/guides/migrating-to-react-query-4.md @@ -282,7 +282,7 @@ It was possible to change the logger globally by calling `setLogger`. In v4, tha + const queryClient = new QueryClient({ logger: customLogger }) ``` -### Undefined is an illegale cache value for successful queries +### Undefined is an illegal cache value for successful queries In order to make bailing out of updates possible by returning `undefined`, we had to make `undefined` an illegal cache value. This is in-line with other concepts of react-query, for example, returning `undefined` from the [initialData function](guides/initial-query-data#initial-data-function) will also _not_ set data. @@ -301,6 +301,14 @@ This is now disallowed on type level; at runtime, `undefined` will be transforme As of v4, React Query is optimized for modern browsers. We have updated our browserslist to produce a more modern, performant and smaller bundle. You can read about the requirements [here](../installation#requirements). +### No _default_ manual Garbage Collection server-side + +In v3, React Query would cache query results for a default of 5 minutes, then manually garbage collect that data. This default was applied to server-side React Query as well. + +This lead to high memory consumption and hanging processes waiting for this manual garbage collection to complete. In v4, by default the server-side `cacheTime` is now set to `Infinity` effectively disabling manual garbage collection (the NodeJS process will clear everything once a request is complete). + +This change only impacts users of server-side React Query, such as with Next.js. If you are setting a `cacheTime` manually this will not impact you (although you may want to mirror behavior). + ## New Features 🚀 ### Proper offline support diff --git a/docs/src/pages/guides/ssr.md b/docs/src/pages/guides/ssr.md index a429afa999..43a59d3b31 100644 --- a/docs/src/pages/guides/ssr.md +++ b/docs/src/pages/guides/ssr.md @@ -202,7 +202,9 @@ This refetching of stale queries is a perfect match when caching markup in a CDN ### High memory consumption on server -In case you are creating the `QueryClient` for every request, React Query creates the isolated cache for this client, which is preserved in memory for the `cacheTime` period (which defaults to 5 minutes). That may lead to high memory consumption on server in case of high number of requests during that period. +In case you are creating the `QueryClient` for every request, React Query creates the isolated cache for this client, which is preserved in memory for the `cacheTime` period. That may lead to high memory consumption on server in case of high number of requests during that period. + +On the server, `cacheTime` defaults to `Infinity` which disables manual garbage collection and will automatically clear memory once a request has finished. If you are explicitly setting a non-Infinity `cacheTime` then you will be responsible for clearing the cache early. To clear the cache after it is not needed and to lower memory consumption, you can add a call to [`queryClient.clear()`](../reference/QueryClient#queryclientclear) after the request is handled and dehydrated state has been sent to the client. diff --git a/docs/src/pages/guides/testing.md b/docs/src/pages/guides/testing.md index fc3a323569..96e8ebf9bd 100644 --- a/docs/src/pages/guides/testing.md +++ b/docs/src/pages/guides/testing.md @@ -88,7 +88,7 @@ const queryClient = new QueryClient({ ## Set cacheTime to Infinity with Jest -`cacheTime` is set to 5 minutes by default. It means that the cache garbage collector timer will be triggered every 5 minutes. If you use Jest, you can set the `cacheTime` to `Infinity` to prevent "Jest did not exit one second after the test run completed" error message. +If you use Jest, you can set the `cacheTime` to `Infinity` to prevent "Jest did not exit one second after the test run completed" error message. This is the default behavior on the server, and is only necessary to set if you are explicitly setting a `cacheTime`. ## Testing Network Calls