Sync Modes
Plan how Tulip modules should use full-sync and on-demand collections without splitting the UI API.
TanStack DB gives us two important shapes for local collections:
- the default collection approach, where the logical dataset is loaded into the client collection
syncMode: "on-demand", where the collection hydrates only the subset requested by the UI
Both are useful. The strategy should be to support both, not to pick one globally.
Default collection mode
This is the simpler model.
- one collection mirrors the working dataset
- live queries can assume rows are already present locally
- table filtering and sorting can often be resolved entirely in the client collection
- optimistic updates are straightforward because the full working set is loaded
Use it when:
- the dataset is bounded
- the screen needs rich local interactions
- loading everything the user needs is acceptable
On-demand mode
This is the safer model for large or naturally segmented datasets.
- the collection only loads requested subsets
- query keys must include the subset identity
- filters and sorting need a server-friendly representation
- pagination and infinite loading become first-class concerns
Use it when:
- the dataset is large
- records are usually viewed inside a parent context
- loading the whole module would be wasteful
- the screen is driven by page, infinite, or subset loading
Examples:
- a time module with many records
- addresses, contacts, or line items under a parent entity
- activity feeds or event streams
When not to use on-demand mode
Avoid on-demand mode when the screen constantly needs cross-record local operations across the whole dataset, such as global local filtering, instant resorting of the full list, or local derived summaries that only make sense if all rows are present.
Component integration strategy
Tulip components should not have to know which sync mode a module picked.
The strategy is:
- keep mutations pointed at the same server procedures regardless of mode
- keep component inputs centered on rows, selection, filters, and actions instead of collection internals
- keep table query state mode-agnostic so server-first and local-first modules can share the same query semantics
- add adapter helpers where needed so a component can consume either live collection data or regular query data
In practice, this means the sync mode decision should live inside the module integration layer, not inside every table, form, or detail component.
Recommended rule
Default to the standard collection mode for bounded working sets. Reach for syncMode: "on-demand" when dataset size or page shape makes full hydration unrealistic.