We built everything with this architecture internally already at Rivet. It's less common than you might expect to have to query cross-DB in practice.
However, we are planning on building a query engine that can operate over multiple databases. One option we're considering is exposing Rivet SQLite as a DuckDB datasource: https://duckdb.org/docs/stable/data/data_sources
I get where you come from, but really needs it to be a whole SQLite instance per database? Wouldn’t be more efficient just logic separation in a larger DB?
Better usage of resources and it always allows a parent style agent do complex queries (e.g: intersection of two different actors data doesn’t need to fetch all, copy and do it in buggy non sql code)
In our experience, most apps don't need cross-tenant queries outside of BI. For example, think about the apps you use on a daily basis: Linear, Slack, ChatGPT all fit well with an actor-per-workspace or actor-per-thread model.
To be clear, we're not trying to replace Postgres. We're focused on modern workloads like AI, realtime, and SaaS apps where per-tenant & per-agent databases are a natural fit.
Using SQLite for your per-tenant or per-agent databases has a lot of benefits:
- Compute + state: running the SQLite database embedded in the actor has performance benefits
- Security: solutions like RLS are a security nightmare, much easier to have peace of mind with full DB isolation per tenant
- Per-tenant isolation: important for SaaS platforms, better for security & performance
- Noisy neighbors: limits the blast radius of a noisy neighbor or bad query to a single tenant's database
- Enables different schemas for every tenant
- AI-generated backends: modern use cases often require AI-generated apps to have their own custom databases; this model makes that easy
A few other points of reference in the space:
- Cloudflare Durable Objects & Agents are built on this model, and much of Cloudflare's internal architecture is built on DO
We recently replaced an isolated feature built on Durable Objects with Rivet Actors, to allow for much better interop with the rest of our infra (which is built on AWS/Vercel), and are happy with it so far.
There have been some small issues but nothing show-stopping, and the Rivet team has been very responsive to help get things sorted (or help us understand when it was us doing something wrong).
Not using the SQLite datastore yet, but I am excited about the possibilities!
Theory, performance, self-host option, estimated cost, etc. And I see you can deploy rivet on Cloudflare DOs. What situation does it help when we can just use wrangler?
By the way, Cloudflare DO is actually self-hostable with workerd to my knowledge, but it's not an out-of-box experience.
Really interesting to see these new compute paradigms. I haven't built anything on Durable Objects yet but I can see the appeal and I'd prefer an OSS option.
SqliteDB per tenant may make sense, not sure about per actor. You really don't want to re-implement database transactions.
Yep, everyone seems to reinventing the actor model from first principles right now.
We're taking a different approach of building the best actor primitive for mainstream languages and letting people build a thin AI layer on top. We did not set out out build for AI when we started it, it was a happy accident.
The lazy migration design is clever for the common case, but I keep getting stuck on what happens when a migration isn't just "add a column." If you need to backfill a derived field or rebuild an index across a restructured table, some unlucky user's request becomes the one that absorbs thirty seconds of migration work instead of the usual milliseconds. And you can't really pre-migrate millions of idle databases either, since the whole point is they only wake on demand. Is there a pattern people are using here, like versioned read paths that serve old-schema data while migrating in the background, or is the practical answer just "don't write heavy migrations"?
swaminarayan | a day ago
[OP] NathanFlurry | a day ago
However, we are planning on building a query engine that can operate over multiple databases. One option we're considering is exposing Rivet SQLite as a DuckDB datasource: https://duckdb.org/docs/stable/data/data_sources
nudpiedo | a day ago
Better usage of resources and it always allows a parent style agent do complex queries (e.g: intersection of two different actors data doesn’t need to fetch all, copy and do it in buggy non sql code)
[OP] NathanFlurry | a day ago
In our experience, most apps don't need cross-tenant queries outside of BI. For example, think about the apps you use on a daily basis: Linear, Slack, ChatGPT all fit well with an actor-per-workspace or actor-per-thread model.
To be clear, we're not trying to replace Postgres. We're focused on modern workloads like AI, realtime, and SaaS apps where per-tenant & per-agent databases are a natural fit.
Using SQLite for your per-tenant or per-agent databases has a lot of benefits:
- Compute + state: running the SQLite database embedded in the actor has performance benefits
- Security: solutions like RLS are a security nightmare, much easier to have peace of mind with full DB isolation per tenant
- Per-tenant isolation: important for SaaS platforms, better for security & performance
- Noisy neighbors: limits the blast radius of a noisy neighbor or bad query to a single tenant's database
- Enables different schemas for every tenant
- AI-generated backends: modern use cases often require AI-generated apps to have their own custom databases; this model makes that easy
A few other points of reference in the space:
- Cloudflare Durable Objects & Agents are built on this model, and much of Cloudflare's internal architecture is built on DO
- https://neon.com/use-cases/database-per-tenant
- https://turso.tech/multi-tenancy
- https://www.thenile.dev/
- Val.town & Replit
> Better usage of resources
I'd be curious to hear more about what you mean by this.
> always allows a parent style agent do complex queries
Do you have a specific use case in mind where agents need to query other agents' data?
fastball | a day ago
There have been some small issues but nothing show-stopping, and the Rivet team has been very responsive to help get things sorted (or help us understand when it was us doing something wrong).
Not using the SQLite datastore yet, but I am excited about the possibilities!
[OP] NathanFlurry | a day ago
ZeroAurora | a day ago
Would it be interesting to write about comparisons against Cloudflare Durable Object to the project README? Both for clarity and marketing reasons.
[OP] NathanFlurry | a day ago
ZeroAurora | 7 hours ago
By the way, Cloudflare DO is actually self-hostable with workerd to my knowledge, but it's not an out-of-box experience.
siliconc0w | a day ago
SqliteDB per tenant may make sense, not sure about per actor. You really don't want to re-implement database transactions.
[OP] NathanFlurry | a day ago
malkosta | a day ago
[OP] NathanFlurry | a day ago
We're taking a different approach of building the best actor primitive for mainstream languages and letting people build a thin AI layer on top. We did not set out out build for AI when we started it, it was a happy accident.
malkosta | 18 hours ago
o175 | 10 hours ago
fastball | 2 hours ago
Personally I think the benefits of lazy outweigh the downside of that single 30s request, but to each their own.