Skip to content

Caching

Every cached entry goes through three phases. invalidate() marks entries stale; it never deletes them.

Phase Read behavior Boundary
Fresh Return cached data. No network request. Data was written to cache.
Stale Return cached data and re-fetch in the background. staleTime elapsed.
Evicted Fetch from the server. expireTime elapsed and the entry was removed.
Scenario Cache UI
First visit ever miss Spinner → data
Return visit, data younger than staleTime fresh Data immediately, no fetch
Return visit, data older than staleTime stale Stale data immediately → silent refresh → fresh data
After mutation stale Data + silent refresh because the mutation invalidated the cache
Network error with cached data stale Stale data remains visible, no crash

You delete an order. The list, the detail page, and every filtered view all need to refresh. Hierarchical cache keys make this one call:

['order'] ← invalidate here
└── ['order', 'list'] all orders page
└── ['order', 'list', 'pending'] filtered view
└── ['order', 'details', '42'] detail page
cache.invalidate(['order']) // ← one call, everything refreshes

See the Guide for full optimistic update and mutation examples.

Cache Do not cache
GET entity lists POST, PUT, or DELETE
GET entity details Search results with volatile params
Data shared across screens Real-time data from WebSocket or SSE
Predictable access patterns such as tabs and navigation Large binaries