In a normal database, you run a query and get a result. That result is instantly stale. Run a second query and it’s stale too, but differently. The two results can disagree with each other, and there’s no way to know.
Not a great start for high-quality software, but you accept it — it’s just how databases work.
You build something. It has multiple users or agents collaborating. Everyone is changing the same data at the same time, and nobody knows what the others just did. Bad things happen.
Making this work properly is called “real-time collaboration,” but it’s really just solving that same inconsistency problem.
You could try to patch it:
- Re-run queries on a timer. That’s expensive, and it still leaves gaps.
- Build a WebSocket system to tell the UI when important data changes. Now you get to maintain a whole separate live push system.
Most people decide to live with it. It’s just how databases work.
Why do databases work this way?
Because live queries are hard to do well.
The obvious approach is to re-run each query when its underlying data changes. But the queries worth watching are usually the ones whose data changes most, so you re-run them constantly. That gets expensive.
There are ways to fight this, but they often push the database toward custom query models and APIs, away from standard web architecture.
So most teams pick a traditional database and live with stale results, rather than opt into a walled garden.
Live queries, no walls
Instead of re-running queries, what if we updated a query result precisely as the underlying data changed? This is called Incremental View Maintenance.
IVM engines like Feldera and Materialize exist today, but they’re built for analytics: a small number of queries known up front over huge datasets. They trade lots of memory and slow startup for optimal incremental updates.
When we were building Zero, we needed something like this, but for application workloads. We wanted to sync large numbers of small dynamic queries.
So we built ZVM. It can maintain thousands of small queries on a single core at 1,000 writes per second.
Until now, ZVM was an implementation detail of Zero — you couldn’t use it on its own. Rindle factors it out into a standalone database. And because of IVM, we don’t need a custom query model: it’s just plain SQL with subscriptions. Use it as the basis of a sync engine, or just use it as a database.
Don’t like SQL?
You can of course use a typed query builder too. It’s just syntax. The core idea is that Rindle is a traditional relational database.
No more stale data. No inconsistent results. Your UI updates when the data does, and collaborators see each other’s changes live.
Bigger than it sounds
Live queries sound like a minor feature. They’re not. Beyond solving data inconsistency and collaboration, live queries are also the foundation for two of the biggest shifts in software today:
- Sync. Efficient live queries are the key to general-purpose sync, because they enable clients to sync only the subset of data they care about. Rindle directly supports Zero, but it can just as easily back TanStack DB or any other sync engine.
- Agents. Long-lived agents need to react when data changes. Live queries wake them on the change, instead of having them poll or re-read everything.
Why Rindle
We built ZVM because we needed it for Zero. But live queries shouldn’t be a special feature of exotic databases. They should just be how data works.