Capítulo 9 de 80

Chapter 9: Important Defaults

Core Idea

TanStack Query ships with aggressive-but-sane defaults (data is stale immediately, failed queries retry 3x with backoff, inactive cache entries are GC'd after 5 minutes) that catch new users off guard until they're made explicit.

Key Concepts

  • Staleness by default: queries are considered stale the instant they resolve unless staleTime says otherwise — "stale" doesn't mean "wrong," it means "eligible for a background refetch."
  • staleTime levels: a number of ms (fresh for that long, then refetch-eligible), Infinity (never stale-refetch, but invalidateQueries() still forces one), or 'static' (stricter than Infinity — blocks even manual invalidation and refetchOn*: "always"; use for data that truly cannot change while the app runs, like boot-time feature flags).
  • Automatic background refetch triggers: new mount of the query, window refocus, network reconnect — independent of any refetchInterval polling you configure.
  • Garbage collection (gcTime): once a query has zero active observers it's "inactive," kept around for gcTime (default 5 minutes) in case it's needed again, then evicted.
  • Retry: failed queries silently retry 3 times with exponential backoff before surfacing an error — configurable via retry/retryDelay.
  • Structural sharing: successful results are diffed structurally so unchanged sub-trees keep the same object reference (helps useMemo/useCallback stability) — JSON-compatible values only; non-JSON values are always treated as changed unless you supply a custom structuralSharing function.

Reference Tables

DefaultValueOverride
staleTime0 (stale immediately)number of ms, Infinity, or 'static'
gcTime5 minutesany ms value
retry3 attempts, exponential backoffretry / retryDelay
Structural sharingon, JSON-compatible values onlystructuralSharing: false or custom function

Key Takeaways

  1. staleTime: 0 (the default) is why a query seems to "refetch too much" — set it deliberately per query instead of fighting the defaults piecemeal.
  2. Use 'static' only for data that cannot change during the app's lifetime; use Infinity for data you still want invalidateQueries() to be able to force-refresh.
  3. Structural sharing is free performance in the vast majority of cases — only disable it when responses are huge and non-JSON or you've measured a real cost.

Connects To

  • Query Retries: full detail on the retry/backoff defaults mentioned here.
  • Window Focus Refetching / Polling: the other automatic-refetch triggers this chapter references.