Stale-while-revalidate means: show the cached data instantly, refetch in the background, and swap in fresh data when it arrives. The user never sees a spinner for data they have seen before.
TanStack Query has two settings for this:
staleTimeis how long data counts as fresh. During this time there is no refetch at all.gcTimeis how long unused data stays in memory before it is removed.
I choose staleTime per resource. It depends on how fast the data changes and how much stale data hurts. Examples:
- A country list can stay fresh for hours.
- A user profile can stay fresh for a minute.
- Stock levels or a chat list need close to zero, with push updates on top.
Refetch triggers, like window focus and reconnect, cover users who come back to a tab.
I invalidate on mutations. For example, after creating a comment, invalidate that post's comment list, not everything. Hierarchical keys such as ["posts", id, "comments"] make targeted invalidation easy, because you can invalidate one branch of the tree.
For data that other users change, I combine short stale times with push events that invalidate specific keys.
- Show cached data at once and refresh it in the background.
staleTimecontrols how long data is fresh.gcTimecontrols how long unused data stays in memory.- Choose the stale time per resource, based on how fast the data changes.
- After a mutation, invalidate only the affected data, using hierarchical keys.
- Push events from the server can trigger invalidation.