Out of the box, TanStack Query is configured with aggressive but sane defaults. Sometimes these defaults can catch new users off guard or make learning/debugging difficult if they are unknown by the user. Keep them in mind as you continue to learn and use TanStack Query:
useQuery or useInfiniteQuery by default consider cached data as stale.To change this behavior, you can configure your queries both globally and per-query using the
staleTimeoption. Specifying a longerstaleTimemeans queries will not refetch their data as often
staleTime set is considered fresh until that staleTime has elapsed.
staleTime to e.g. 2 * 60 * 1000 to make sure data is read from the cache, without triggering any kinds of refetches, for 2 minutes, or until the Query is invalidated manually.staleTime to Infinity to never trigger a refetch until the Query is invalidated manually.staleTime to 'static' to never trigger a refetch, even if the Query is invalidated manually.
'static'andInfinityboth prevent staleness-based refetches, but'static'is stricter:queryClient.invalidateQueries()can invalidate a query withstaleTime: Infinity, but has no effect onstaleTime: 'static'.refetchOnMount,refetchOnWindowFocus, andrefetchOnReconnectset to"always"are also blocked by'static'. Use'static'for data that cannot change while the app is running: feature flags fetched at boot, user permissions loaded at login, static reference tables. UseInfinitywhen you still want manual invalidation to work.
Setting
staleTimeis the recommended way to avoid excessive refetches, but you can also customize the points in time for refetches by setting options likerefetchOnMount,refetchOnWindowFocusandrefetchOnReconnect.
Queries can optionally be configured with a refetchInterval to trigger refetches periodically, which is independent of the staleTime setting. See Polling for details.
Query results that have no more active instances of useQuery, useInfiniteQuery or query observers are labeled as "inactive" and remain in the cache in case they are used again at a later time.
By default, "inactive" queries are garbage collected after 5 minutes.
To change this, you can alter the default
gcTimefor queries to something other than1000 * 60 * 5milliseconds.
Queries that fail are silently retried 3 times, with exponential backoff delay before capturing and displaying an error to the UI.
To change this, you can alter the default
retryandretryDelayoptions for queries to something other than3and the default exponential backoff function.
Structural sharing only works with JSON-compatible values, any other value types will always be considered as changed. If you are seeing performance issues because of large responses for example, you can disable this feature with the
config.structuralSharingflag. If you are dealing with non-JSON compatible values in your query responses and still want to detect if data has changed or not, you can provide your own custom function asconfig.structuralSharingto compute a value from the old and new responses, retaining references as required.
Have a look at the following articles from our Community Resources for further explanations of the defaults:
