Skip to content

Unexpected staleTime of 1000ms set on fetchQuery #8986

@lucas0530

Description

@lucas0530

Describe the bug

Issue Description

When using react-query's fetchQuery under certain conditions, the staleTime option is unintentionally set to 1000ms internally, even though it was not explicitly specified.

Steps to Reproduce

Execute a fetchQuery on page A with a specific query key without explicitly setting staleTime.

Execute useSuspenseQuery on page B with the same query key, which internally sets staleTime to 1000ms.

Navigate back to page A and execute fetchQuery again with the same query key. It unintentionally reuses the previously set 1000ms staleTime.

Your minimal, reproducible example

https://codesandbox.io/p/devbox/intelligent-carlos-forked-dnf7d7?workspaceId=ws_3jAYUrwzD7RnnukpanRdE9

Steps to reproduce

  1. When the Test button is clicked, the cache is stored without an explicitly set staleTime option.
  2. Upon clicking the Show button, the existing cache is updated with a staleTime of 1000ms (due to the previous internal ensure utility logic).
  3. Clicking the Test button again maintains the cache with the previously set staleTime of 1000ms.
  4. If the Show button is clicked again within 1000ms after step 3, the queryFn does not get triggered.

It appears that because fetchQuery executes with a 1000ms staleTime, useSuspenseQuery considers the given query key fresh and avoids invoking the queryFn.

Expected behavior

Additional Issue Caused

Due to this behavior, if useSuspenseQuery is executed again within 1000ms after step 3 with the same query key, it considers the data as fresh. Therefore, the queryFn for background fetching does not get called at all, leading to potential issues of not retrieving up-to-date data from the server.

Expected Behavior

When not explicitly set, fetchQuery should use the default staleTime of 0ms as documented.

Options from useSuspenseQuery should not unintentionally affect subsequent fetchQuery calls. Each query should handle its options independently.

How often does this bug happen?

None

Screenshots or Videos

No response

Platform

  • MacOS
  • Chrome All Versions

Tanstack Query adapter

None

TanStack Query version

v4, v5

TypeScript version

No response

Additional context

No response

Activity

TkDodo

TkDodo commented on May 1, 2025

@TkDodo
Collaborator

Navigate back to page A and execute fetchQuery again with the same query key. It unintentionally reuses the previously set 1000ms staleTime.

That’s not what’s happening. I’ve modified your example to show more log statements from within the QueryFunctions: https://codesandbox.io/p/sandbox/intelligent-carlos-forked-hrlkk9?file=%2Fsrc%2FApp.tsx%3A37%2C7

You can see that whenever you click TEST, the queryFn is executed. The staleTime is not reused. It can’t be reused because staleTime is an observer-level property that doesn’t exist on a Query - it exists on QueryObserver (and is amended for imperative methods like fetchQuery).

So, you can call fetchQuery whenever you want, it will execute.

if useSuspenseQuery is executed again within 1000ms after step 3 with the same query key, it considers the data as fresh. Therefore, the queryFn for background fetching does not get called at all, leading to potential issues of not retrieving up-to-date data from the server.

Yes, useSuspenseQuery has a “minimal” staleTime of one second. That’s necessary because of how suspense works: it unmounts your component to show the fallback. Then, once data comes in, it will mount your component again. With a staleTime of zero that would trigger another immediate background refetch, which isn’t wanted.

Sorry if this is causing issues for you but I don’t think I’ll be spending time to improve this. The sequence to reproduce is pretty narrow, as you need to have been on the page where useSuspenseQuery is executed, move away from it, trigger a fetch and then within one second move to the page with useSuspenseQuery again. And even then, you’ll get data from roughly 500ms “before”.

If that’s really an issue, you can always run queryClient.fetchQuery() in a useEffect in addition on the page where you call useSuspenseQuery.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @TkDodo@lucas0530

        Issue actions

          Unexpected staleTime of 1000ms set on fetchQuery · Issue #8986 · TanStack/query