Guides & concepts

Cache keys and invalidation

What the key contains, and why each position is where it is.

[...queryKeyPrefix, service, endpoint, resolvedPath, params?]
  • service and endpoint lead, so prefix invalidation keeps working.
  • resolvedPath follows, so two calls differing only by path parameter are separate entries.
  • params is omitted when empty, and keys whose value is undefined are dropped — TanStack hashes with JSON.stringify, which drops them anyway, so keeping them would split the cache between two identical requests.
invalidate.ts
// Everything under the users service
qc.invalidateQueries({ queryKey: api.users.queryKey });

// Every call of users.detail, whatever the path params
qc.invalidateQueries({ queryKey: ['users', 'detail'] });

// One resource
qc.invalidateQueries({
  queryKey: api.users.detail.withPathParams({ id: '42' }).queryKey,
});
// ['users', 'detail', '/users/42']

An endpoint with unbound path parameters keeps its placeholder — ['users', 'detail', '/users/:id'] — so it cannot collide with a bound one.

Mutation keys match

mutationKey uses the same builder, so useMutationState can tell two mutations on different resources apart.