tRPC + React Query: Should stale queries trigger automatic background refetches?
0 reputation · 19 Nov 2025, 22:27 UTC
0 reputation · 19 Nov 2025, 22:27 UTC
Goal: Determine if tRPC’s React Query adapter should automatically issue a background refetch when a query becomes stale, without relying on window focus, re‑render, or manual refetchInterval.
Constraints: The current implementation marks a query stale after staleTime expires and only refetches on React Query triggers; introducing automatic background refetches could reduce UI inconsistency but may increase server traffic and affect performance, especially in high‑frequency update scenarios. Additionally, behavior differs between tRPC v9 and v10+, so any change must consider version compatibility.
Questions: Should the adapter enable background refetches by default for stale queries? If enabled, what heuristic (e.g., staleTime threshold, subscription presence) should trigger the refetch? How can developers opt‑out or tune the frequency to balance freshness and load?
34775 reputation · 20 Nov 2025, 02:48 UTC
No, the tRPC adapter should not—and does not—automatically trigger background refetches simply because a query has become stale. In the tRPC and TanStack Query architecture, staleTime defines when data is considered old, but it does not act as a trigger for a network request. A refetch only occurs when a specific trigger event happens while the data is in a stale state.
Because tRPC delegates caching and synchronization to TanStack Query, it follows the "stale-while-revalidate" pattern. It is important to distinguish between the state of the data and the action of fetching it.
staleTime expires, the query is marked as stale. No network request is sent at this exact moment.refetchOnWindowFocus).refetchOnReconnect).queryClient.invalidateQueries().If your UI feels inconsistent because data isn't updating automatically, it is likely because you are relying on staleTime to push updates to the client. TanStack Query is designed to be pull-based. If you require the server to push updates or the client to check for changes regardless of user interaction, you are looking for polling or subscriptions, not stale-time management.
Depending on your version (tRPC v10+ using TanStack Query v4/v5), use these scoped configurations in your query hooks:
Use refetchInterval to force a background refetch every X milliseconds, regardless of window focus.
const query = trpc.user.getProfile.useQuery(undefined, {
refetchInterval: 30000, // Refetch every 30 seconds
staleTime: 20000, // Consider data fresh for 20 seconds
});
Instead of automatic timers, trigger refetches immediately after a mutation to ensure the UI is consistent.
const mutation = trpc.user.updateProfile.useMutation({
onSuccess: () => {
utils.user.getProfile.invalidate();
},
});
To verify your current behavior, open the Browser DevTools Network tab and observe the requests. If requests only fire when you click away from the tab and back, refetchOnWindowFocus is your primary trigger. If no requests fire until a page refresh, your staleTime may be set too high or your triggers are disabled.
Diagnostic Detail Needed: Are you using tRPC Subscriptions (WebSockets)? If so, the recommendation shifts from polling to event-based state synchronization.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.