惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

人人都是产品经理
人人都是产品经理
Blog — PlanetScale
Blog — PlanetScale
MyScale Blog
MyScale Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
WordPress大学
WordPress大学
Vercel News
Vercel News
D
Docker
博客园 - 聂微东
T
Tailwind CSS Blog
aimingoo的专栏
aimingoo的专栏
云风的 BLOG
云风的 BLOG
D
DataBreaches.Net
B
Blog RSS Feed
酷 壳 – CoolShell
酷 壳 – CoolShell
博客园 - Franky
Microsoft Security Blog
Microsoft Security Blog
美团技术团队
F
Fortinet All Blogs
MongoDB | Blog
MongoDB | Blog
T
The Blog of Author Tim Ferriss
GbyAI
GbyAI
N
Netflix TechBlog - Medium
G
Google Developers Blog
腾讯CDC

TanStack Blog

TanStack + Vercel Partnership | TanStack Blog TanStack AI Enters the RC Phase | TanStack Blog Inside a TanStack Router Navigation | TanStack Blog Form v2 is here: All you need to know about the alpha | TanStack Blog Announcing TanStack Table V9 | TanStack Blog TanStack Has a New Look | TanStack Blog Introducing TanStack Markdown and TanStack Highlight | TanStack Blog We Removed React Server Components from TanStack.com | TanStack Blog We Stopped Using RSC on TanStack.com | TanStack Blog Inside TanStack Table V9 Reactivity | TanStack Blog Run Any Coding Agent in a Sandbox, With One chat() Call | TanStack Blog TanStack Start and TanStack AI Win 2026 Open Source Awards | TanStack Blog How an Underrated Refactor Saved 90% Memory Usage | TanStack Blog TypeScript Performance in TanStack Table V9 | TanStack Blog TanStack AI Beta: The Switzerland of AI Tooling Grows Up | TanStack Blog TanStack Table V9: Taking Form | TanStack Blog TanStack AI: Your MCP, your way | TanStack Blog TanStack Start Adds First-Class Rsbuild Support | TanStack Blog Introducing Experimental Workflows and Orchestrators in TanStack AI | TanStack Blog Chat UIs Are Lists Until They Aren't | TanStack Blog Structured Output That Remembers Across Turns | TanStack Blog TanStack Virtual just got a lot faster, and finally handles iOS | TanStack Blog TanStack AI now fully speaks AG-UI | TanStack Blog Stop Waiting on JSON: Stream Structured Output with One Schema | TanStack Blog Hardening TanStack After the npm Compromise | TanStack Blog Postmortem: TanStack npm supply-chain compromise | TanStack Blog Who Owns the Tree? RSC as a Protocol, Not an Architecture | TanStack Blog TanStack AI Just Learned to Compose Music | TanStack Blog Your AI Tool Calls Should Fail at Compile Time, Not in Production | TanStack Blog One Flag, Every Chunk: Debug Logging Lands in TanStack AI | TanStack Blog
TanStack DB 0.5 . Query-Driven Sync | TanStack Blog
co-authored by Sam Willis, Kevin De Porre, and Kyle Mathews · 2025-11-12 · via TanStack Blog

by Sam Willis, Kevin De Porre, and Kyle Mathews on Nov 12, 2025.

Query-Driven Sync

You don't need a new API for every component. With 0.5, the component's query is the API call.

No custom endpoint. No GraphQL resolver. No backend change. Just write your query and TanStack DB figures out exactly what to fetch.

We're releasing TanStack DB 0.5 today with Query-Driven Sync. A feature that fundamentally changes how you think about loading data.

React's breakthrough was making components pure functions of state: UI = f(state). You describe what you want to render, React handles the how.

TanStack DB brings the same philosophy to data: view = query(collections). You describe what data you need. DB handles the fetching, caching, and updating, even across 100k+ row datasets.

The difference? React recomputes the view when state changes. TanStack DB recomputes the query when data changes. And optimizes the network calls automatically.

TanStack DB is a client-first store for your API powered by differential dataflow. A technique that recomputes only what changed. When you mark a todo complete, DB updates query results in <1ms on a modern laptop, even with 100,000+ rows in memory.

This isn't just fast filtering. It's live queries that incrementally maintain themselves as data changes. Effortless optimistic mutations that instantly update all affected queries, then reconcile with the server. And a normalized collection store that eliminates duplicate data and keeps everything coherent.

When we released TanStack DB 0.1 in July, we described the two options teams face and that TanStack DB enables a new Option, C:

Option A. View-specific APIs (fast render, slow network, endless endpoint sprawl)

Option B. Load-everything-and-filter (simple backend, sluggish client)

Option C. Normalized collections + differential dataflow (load once, query instantly, no jitter)

Since we released the first beta in July, we've gotten the same question over and over:

This looks great for loading normalized data once, but what if my users table has 100,000 rows? I can't load everything.

They're right. Before 0.5, collections loaded their entire dataset upfront. That works beautifully for many apps with datasets in the thousands of rows, but it's not a one-size-fits-all solution.

Here's what we realized: a collection shouldn't dictate what data loads. Your queries should.

A collection defines the schema and security boundaries for a data domain. Your live queries define which subset of that domain to load right now.

This led to three sync modes, each optimized for different use cases:

Eager mode (default & only mode before v0.5): Load entire collection upfront. Best for <10k rows of mostly static data: user preferences, small reference tables.

On-demand mode: Load only what queries request. Best for large datasets (>50k rows), search interfaces, catalogs where most data won't be accessed.

Progressive mode: Load query subset immediately, sync full dataset in background. Best for collaborative apps where you want instant first paint AND sub-millisecond queries for everything else.

Most apps use a mix. Your user profile? Eager. Your products catalog? On-demand. Your shared project workspace? Progressive.

Let's see how each works.

With 0.5, you add one line to your collection:

Now when you write this query:

TanStack DB automatically calls your queryFn with:

No custom API endpoint. No GraphQL schema changes. Just a general-purpose products API that accepts filter parameters.

Your component's query becomes the API call.

If you're familiar with Relay or Apollo, this should feel familiar: components declare their data needs, and the framework optimizes fetching and updates. The difference? You get Relay-style normalized caching and automatic updates without GraphQL. Your REST, GraphQL, or tRPC API stays simple, your queries stay powerful, and differential dataflow keeps everything fast client-side.

"Wait," you're thinking, "doesn't this create N+1 query problems?"

No. And here's why the performance story is actually better than custom APIs.

Automatic request collapsing

Multiple components requesting the same data trigger exactly one network call:

TanStack DB compares predicates across all live queries and deduplicates requests automatically.

Subset matching and delta loading

When you navigate from viewing 10 products to viewing 20, DB doesn't reload everything:

Already-loaded rows are reused; only the new window crosses the wire. The collection tracks which predicates it has already satisfied and only fetches the delta.

Join optimization

Complex joins don't cause request explosions. They trigger a minimal set of filtered requests:

DB analyzes the join to determine exactly which related records are needed, then fetches them in a single batched request.

Respects your cache policies

Query Collection integrates with TanStack Query's staleTime and gcTime:

You get TanStack Query's sophisticated caching plus DB's intelligent subset tracking.

The result: Fewer total network requests than custom view-specific APIs, with better cache utilization and zero endpoint sprawl.

On-demand mode is great for search interfaces and catalogs where you'll never touch most of the data. But what about collaborative apps where you want the full dataset client-side for instant queries and offline access, but also want fast first paint?

That's progressive mode: load what you need immediately, sync everything in the background.

Now your first query loads in ~100ms with a targeted network request. While the user interacts with that data, the full dataset syncs in the background. Once complete, all subsequent queries (even complex joins and filters) run in sub-millisecond time purely client-side.

Progressive mode shines with sync engines like Electric, Trailbase, and PowerSync. With traditional fetch approaches, loading more data means re-fetching everything, which gets expensive fast. But sync engines only send deltas (the actual changed rows), making it cheap to maintain large client-side datasets. You get instant queries over 10,000s of rows without the network cost of repeatedly fetching all that data.

With REST APIs, progressive mode is less common since updates generally require full re-fetches. But for sync engines, it's often the sweet spot: fast first paint + instant everything else.

Query-Driven Sync is designed to work with your existing REST, GraphQL, or tRPC APIs. No backend migration required: just map your predicates to your API's parameters (as shown below) and you're done.

For teams using sync engines like Electric, Trailbase, or PowerSync, you get additional benefits:

  • Real-time updates via streaming (no polling required)
  • Automatic predicate translation (no manual mapping needed)
  • Delta-only syncing (only changed rows cross the wire)

For example, Electric translates your client query directly into Postgres queries, applies authorization rules, and streams updates. Your component's query becomes a secure, real-time, authorized Postgres query, no API endpoint needed.

Collections abstract the data source. Start with REST. Upgrade to sync when you need real-time.

Query Collection is designed for REST, GraphQL, tRPC, and any other API-based backend. When you enable syncMode: 'on-demand', TanStack DB automatically passes your query predicates (where clauses, orderBy, limit) to your queryFn as expression trees in ctx.meta.loadSubsetOptions. You write the mapping logic once to translate these into your API's format.

We provide helper functions to make this straightforward:

For APIs with custom formats (like GraphQL), use parseWhereExpression with custom handlers:

You write this mapping once per collection. After that, every query automatically generates the right API calls.

Can't modify your API? Your mapping doesn't need to be precise. Many queries can map to a single broad API call. For example, any product search query with category "hardware" could map to GET /api/products?category=hardware. TanStack DB will apply the remainder of the query client-side. As your API evolves to support more predicates, your client code doesn't change: just update the mapping to push down more filters. Start broad, optimize incrementally.

Full Query Collection predicate mapping documentation →

Query-Driven Sync (0.5) completes the core vision: intelligent loading that adapts to your queries, instant client-side updates via differential dataflow, and seamless persistence back to your backend. We're targeting 1.0 for December 2025, focusing on API stability and comprehensive docs.

This is new. We need early adopters. Query-Driven Sync works and ships today, but it's fresh. If you try it, we'd love your feedback on rough edges or API improvements. Join us in Discord or open GitHub issues.

If you have ideas for new collection types based on Query-Driven Sync, please reach out. The interface is very powerful and we have lots of interesting ideas for how it can be used.

Try it today


Collections define schemas and security boundaries. Queries define what loads and when. Your components define UIs. Finally, each concern is separate. And your data layer adapts to how you actually use it.