-
-
Notifications
You must be signed in to change notification settings - Fork 3.5k
Description
Describe the bug
When using PersistQueryClientProvider with a large cache (≥5,000 queries), each setQueryData triggers a full dehydrate() and persistence cycle.
This causes noticeable main-thread blocking (1–3 seconds) and complete UI freeze as cache size grows.
Sandbox features:
- Toggle to enable/disable query persistence
- Simulates adding “work items” (each creates ~5–6 related queries)
Behavior in sandbox:
- Persistence OFF → No lag, even with 10,000+ queries
- Persistence ON → Adding just 100 new work items (~500 queries) causes >1 second freeze when cache already has ~5,000 queries
- Data in sandbox is extremely lightweight — in real apps with richer data, the stall is significantly worse
Root cause
PersistQueryClientProvider subscribes to cache changes and calls persistClient() & dehydrate() on every cache mutation, including every setQueryData.
With thousands of queries, this repeatedly serializes the entire cache, blocking the main thread.
Your minimal, reproducible example
https://codesandbox.io/p/sandbox/fragrant-flower-59grjn
Steps to reproduce
Steps to reporduce:
- Click
Add 500 work items
twice. - When we have 5k total queries, open the performance tab.
- Click
Add 100 work items
- Observe the main thread being blocked for more than 1 second by reactQuery internals
Expected behavior
- Persistence should be batched or throttled, not triggered on every setQueryData.
- Alternatively, React Query could maintain an in-memory dehydrated state inside
PersistQueryClientProvider
and reuse it, rather than re-serializing the entire cache every time.
How often does this bug happen?
Every time
Screenshots or Videos
Live lag in the code sandbox:
Screen.Recording.2025-10-17.at.11.31.32.AM.mp4
Each long task is after adding 100 work items:
Platform
- OS: Mac OS
- Browser: Chrome
- Version: 140.0.7339.133
Tanstack Query adapter
None
TanStack Query version
v5+
TypeScript version
No response
Additional context
Cache Population Pattern
We're using a pattern where list mutations populate related entity caches:
queryClient.setQueryData(["works", "detail", work.id], work);
queryClient.setQueryData(["users", "detail", work.owner.id], work.owner);
queryClient.setQueryData(["teams", "detail", work.team.id], work.team);
...etc
Each of these calls triggers persistence, causing repeated dehydrations and full-cache serialization.
Observations from my app:
We saw react-query blocking the main thread for 6-7 seconds consistently on many list calls after enabling the persistent query cache.