Apollo 9: Cache Invalidation
easy⏱ 5 mincourseapollo
evict, gc, refetchQueries, resetStore
Apollo provides four invalidation strategies:
- cache.evict({ id }) — Remove a specific object from the cache by its cache ID (e.g.,
Todo:5). Fast and surgical.
- cache.gc() — Garbage collect unreachable objects. Call after
evict to clean up orphaned references.
- refetchQueries — Re-execute specified queries after a mutation. Simpler but slower (network round-trip).
- client.resetStore() — Nuclear option: clears the entire cache and refetches all active queries. Use for logout flows.
// Surgical eviction
cache.evict({ id: cache.identify(deletedTodo) });
cache.gc();
// Refetch after mutation
useMutation(DELETE_TODO, {
refetchQueries: [{ query: GET_TODOS }],
});
// Full reset (logout)
client.resetStore();
Implement eviction after delete
Create a TodoList with a delete button per item. Use useMutation(DELETE_TODO) with an update callback. In the callback, call cache.evict({ id: cache.identify(deletedTodo) }) followed by cache.gc(). The item should disappear from the list immediately without refetching the full query. Also add a "Reset All" button that calls client.resetStore().
Surgical eviction vs full refetch
Prefer cache.evict + cache.gc when deleting a single item — it's instant and doesn't hit the network. Use refetchQueries when the server might reorder or recompute results (e.g., deleting an item changes rankings). Use resetStore only for auth state changes (login/logout) when the entire cache is suspect. The more precise your invalidation, the faster your UI.
Garbage collection strategy
After evicting an object, other cached objects may still reference it (e.g., a user's posts array contains a reference to evicted Post:5). cache.gc() traverses the cache and removes these dangling references. Always pair evict with gc. You can also use cache.evict({ id, fieldName }) to remove a single field instead of the whole object — useful when you want to force a re-fetch of just one field.