-
Notifications
You must be signed in to change notification settings - Fork 28
feat: d1 multi-tenancy #17
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
|
Added
Now we should be able to: function createTenantDb(tenantDatabaseId: string) {
return drizzle({
accountId: 'your-cloudflare-account-id',
databaseId: tenantDatabaseId,
token: 'your-cloudflare-api-token',
});
} |
|
Can split schema now with the CLI migrate command - detects if multi-tenancy setting is enabled and if so splits based on configuration. |
|
Added PR to better-auth for Adapter Router - this would handle determining which database to hit (main or tenant) based on the model being queried.
|
Schema splittingAdded full drizzle support for the tenant schema, so now you have Tenant MigratingApplying new migrations to existing tenants now looks like: |
CLIbetter-auth-cloudflare |
commit: |
|
This is still unstable - the D1 orchestration works well but the BetterAuth Adapter split across two databases isn't nice to work with. |
@zpg6 I would like this feature and am willing to contribute. Can you expand on what you have in mind to make the BetterAuth Adapter split experience better? |
Hi @ataylorme ! TLDR: try to run it and feel the pain points. It could work but it needs more adapter logic and will have some limitations for sure. It's just fragile.
|
|
That is quite a lot of pain points. I was hoping to have everything on CloudFlare but Neon or similar with Hyperdrive seems like the path of least resistance compared to overcoming the above. I came across a blog post on D1 sharding architecture that describes a Universal ID-Based Sharding approach that might reduce some of the fragility here. The key idea: embed shard/routing metadata directly in record IDs such as The |
This is awesome! 👏 I think you may have found the answer to the biggest pain point |
|
@zpg6 I had Copilot take a first pass at a hybrid approach. Mind taking a look and seeing if it is a direction you are interested in pursuing? |
I like the plan at a high level, we should pursue it. Before we go too far, I want to check back in on how this handles the separate drizzle migrations. Still have to tackle the "relationships mapping" adapter a bit I think. Add a few plugins to trigger the change in schema. |
|
Oh yeah, I’m not suggesting to accept the copilot code but it is a good reference to get some ideas |



D1 Multi-Tenancy
What is this? - Well, isolating data for your customers into separate databases by-user or by-organization is a common requirement. This offers that capability but in a way that feels native to better-auth. Utilizes hooks for when users and organizations are created and deleted to likewise create and delete the tenant databases. We added some support to the CLI to make this fit, and we extended both Drizzle and BetterAuth to make this happen.
TODOs
cloudflareD1MultiTenancy.d1-httpthat wraps Cloudflare's D1 Rest API's endpoint to execute raw SQL. This is needed since current driver only supports your tenant DBs can't be "bound" to your Worker (ie in your wrangler.toml).feat: REST-based D1- feat: REST-based D1 drizzle-team/drizzle-orm#4881feat: AdapterRouter (experimental): feat: AdapterRouter (experimental) better-auth/better-auth#4236d1-httpdriver andadapterRouterintocloudflareD1MultiTenancyplugin.examples/opennextjs-org-multi-tenancyexample that demonstrates a multi-tenant birthday appdocs/d1-multi-tenancyexamples/opennextjs-org-multi-tenancyLimitations
How it Works - Routing to the correct database