Not sure if it's what you need but check this.. https://docs.tenantsdb.com/connections/postgresql.html
Why did you use RLS?
Short answer: with TenantsDB the global table lives inside each tenant's own database, so your foreign keys stay exactly as they are. Here's the shape of it: https://preview.redd.it/lg2j5a8mz45h1.png?width=1534&format=png&auto=webp&s=67053a5f9a1f59482ab305f51105917dcbe1134d sports is small reference data, so TenantsDB ships it into every tenant database as part of the schema. sports and events sit side by side in the same database, so events.sport\_id -> [sports.id](http://sports.id) is a normal foreign key, fully enforced. Add a sport, deploy once, every tenant has it. your own company data (staff, billing, the plans you sell) stays in a control database your app owns. The app reads it to find which tenant a user belongs to, then connects to that tenant's database. Foreign keys inside the control DB are normal too. Anything you manage centrally, your app references by id, the same pattern you already use across services. moving an existing shared DB over? The importer spots any table without a tenant\_id and lets you mark it as shared reference data, then copies it into every tenant for you: [https://tenantsdb.com/blog/migrate-shared-database-to-isolated-tenants](https://tenantsdb.com/blog/migrate-shared-database-to-isolated-tenants) and having a lot of tenant-agnostic data is the easy side of TenantsDB, not a reason to avoid it. You design those shared tables once in the schema and TenantsDB deploys them into every tenant for you. Ten tenants or thousand, same single schema, one deploy. The volume just rides along, it adds no extra work.
Fair. The one thing I'd push back on is database-per-tenant being an operational headache. That's the reputation, not the reality when provisioning and routing are handled for you. One of our customers moved off RLS in an afternoon. No rewrite, just an app-side refactor: same postgresql:// connection, ORM and migrations unchanged, tenants get their own database on signup and queries route on their own. No session variable, no policy to maintain. It doesn't replace knowing your security model. It just removes one class of mistake.
Your core point is right: isolation has to live in the database, and automated cross-tenant tests are what catch regressions. But RLS is a weak foundation for it. Correctness becomes a tax you pay forever. Every new table, view, function, storage policy, and edge function is one more place to forget the membership check. That's your own "introduced during feature development" point, and it never goes away. You're betting on every policy being right on every object, indefinitely, and a single miss leaks customer data across tenants. Physical isolation removes the bug class instead of asking you to defend against it: • RLS: one shared table, isolation enforced by policy logic you write and maintain on every object. One wrong policy means a cross-tenant leak. • Physical DB per tenant: no shared table to leak from. A query in tenant A's database cannot return tenant B's rows. There is no policy to misconfigure. • RLS: isolation is "enforce it correctly everywhere, forever." • Physical: breaking isolation is structurally impossible. I build TenantsDB, which does exactly this: a physically isolated Postgres database per tenant, provisioned on signup, reached over a standard postgresql:// connection so your ORM and migrations don't change. Flagging that it's mine so you know where I'm coming from. I wrote up the full reasoning here: [https://tenantsdb.com/blog/why-we-stopped-using-row-level-security](https://tenantsdb.com/blog/why-we-stopped-using-row-level-security) On your automated-test point: a thing customers rely on is an integration test that spins up two tenants and asserts one can't see the other, run against live infra. Provable isolation, the testing angle you're recommending, except the database guarantees it instead of the policy layer. What do your tenant counts look like?
RLS is a filter not isolation. You can check our blog here: https://tenantsdb.com/blog/why-we-stopped-using-row-level-security
In the last 3 years the definition of MVP is heavily changed. Everything is moving too fast. By the time you create your "mvp" on lovable, somebody with more knowledge can create your mvp in a week to a month. Depending on the project of course. I would recommend to use lovable only for visual concepts not the actual production code. This is what I used to with lovable as a scratch pad to see how the idea would look on e web page. This was a year ago. Now claude do the sam thing and much better. My honest recommendation is to stay away from lovable and go straight into actual coding. Yes it will be hard at first but you ll learn along the way and will know how to debug better.
multi-tenant scaling is the question that bites you year 2-3, not year 1 but its a bigger problem to solve later. RLS works fine for the first 50 tenants. somewhere around 200 with \~1M rows each you start hitting the predictable stuff. RLS overhead compounds on every query. pgbouncer in transaction mode doesn't play nice with set app.tenant\_id. and silent filter bugs eat real engineering time. then one enterprise customer asks for data residency or a dedicated db and suddenly it's a multi-week project. couple of options when you hit that wall: separate supabase project per tenant works but managing 50+ projects gets hairy fast. provisioning, migrations, billing all multiply. schema-per-tenant in one supabase, better isolation but running migrations across 500 schemas has its own pain. db-per-tenant on a separate orchestration layer is the strongest isolation. hardest to operate without tooling though. some teams build it internally.
The tool looks genuinely useful for teams that are committed to the shared-DB + RLS path. the failure modes you list are real, and "the same code is either correct or catastrophically wrong, depending entirely on database state your AI agent never sees" is the cleanest one-line indictment of the model i've read. The thing that pushed us off RLS entirely (we hit all five of these in production at different points) was realizing the bug class doesn't exist if there are no other tenants in the database to leak: \- no shared rows to forget a filter on \- no policies to misconfigure or set to \`using (true)\` \- no SECURITY DEFINER bypass surface \- service-role key only sees one tenant's DB \- transaction-mode pgbouncer + missed \`SET LOCAL\` becomes a non-issue We ended up building our own per-tenant database orchestration layer (TenantsDB) for exactly this reason. Each tenant gets a real isolated database, schema versioning is coordinated across all of them, and the audit question becomes trivial because there's nothing to audit. not saying RLS auditing is wrong. For teams that can't move off shared infra, your tool is the right..
Both fair concerns. real answer to either flips a lot based on scale (50 tenants vs 5000) and stack. dm me and i can show how i got past it..
Happy to compare notes if useful, been deep in this for a while now...
Your honesty about not being technical is actually a strength. Most people fake it and end up worse off. You're asking the right questions, that already puts you ahead. On scaling and multi-tenancy from day one, here's the simple version. In your meditation app, every user is a row in your database. That's fine for a B2C app, low sensitivity, no compliance pressure. The "multi-tenancy" thing matters more if you ever pivot to selling to companies, (and you want to do this for more revenue) like corporate wellness programs where each company has their own employees using your app. Then each company would want their data separated. Not something you need today, just something to keep in your back pocket. Things you can actually ask your dev that will tell you a lot: * Are the API keys only on the server, never inside the mobile app * Is RLS turned on for every single table * Where are user passwords stored, and are they hashed * Are backups running automatically You don't need to understand the answers deeply. You just need to ask. A good dev explains it patiently. A bad one gets defensive. That alone tells you what you need to know. Keep going. You're closer than you think.
My honest advices is , and i am assuming you have some idea of whats goin on, do everything yourself. You dont need to commission anything to anybody for a meditation app. Times have changed. I used to be in your position 5 years ago where i had a team, not anymore. Secondly, think scaling and multi-tenancy from day one.
Read this with interest because I went the other direction. Ran self-hosted Supabase on cx22 for a few months and the box dropped on me twice during launch traffic. cx22 inventory is also a coin flip in some regions, you reboot at the wrong time and the VM doesn't come back up immediately. Fine for a hobby, not fine for production. A few of your pain points are actually solved if you split the problem differently. PITR you're cobbling with WAL backups. That's the right idea but the operational cost is real. Built-in PITR exists on managed DB platforms without paying Supabase prices. Branching not being git-nice. The reason it's painful is because schema lives in one place and you're versioning it manually. If your DB layer treats schema as a versioned blueprint that deploys to multiple environments with one command, branching stops being a separate problem. Single point of failure. The cx22 going down taking your app with it is the real story here. Multi-tenant isolation matters here too, even for a single app. If your customer data is in one DB and that DB goes down, every customer is down. If each customer has their own DB on a fleet of backing instances, one node failure takes out a slice, not everyone. Multi-tenant isolation is the bigger thing nobody mentions in self-host vs cloud threads. The moment you have customers with sensitive data, the question stops being "Supabase or self-host" and becomes "how do I prove tenant A's data is separated from tenant B's." RLS doesn't pass an audit. Self-host doesn't either. There's a layer that handles this, DB-per-tenant with a proxy that routes wire-protocol connections, schema deploys across all tenants in parallel, zero-downtime tier migrations. That's TenantsDB, what I build. Free up to 10 tenants and isolation is built into the architecture, not bolted on. [docs.tenantsdb.com](http://docs.tenantsdb.com) if you want detail. Your cost math is correct for an indie app though. If you're under 1000 MAU and don't have enterprise customers, self-hosting wins on price.
Separate databases per tenant, yes. Not separate servers for each one. One backing instance runs many tenant DBs. Each tenant gets their own logical database, so there's no row-level filter to mess up. The tenants who need more (compliance, noisy load) get moved to their own VM. A proxy in front makes the app side painless. You connect with a standard driver to one endpoint, it routes to the right tenant DB. Schema changes deploy to all tenants in parallel.
Multi-tenant with tenant\_id works until someone forgets a scope somewhere. Usually a background job, sometimes a migration. The bug class exists until the data is actually separated. RLS covers the obvious read paths but misses migrations running as superuser, SECURITY DEFINER functions, replication streams, anything that doesn't go through the policy. You find out the hard way. Branching per PR is great until you realize production has 50 tenants and your branch has 1. The branch doesn't represent what production looks like. Cognitive load actually gets worse over time with the integrated-platform path. You end up learning Supabase's opinions on everything instead of picking tools you already know. There's an architecture that solves all of this cleanly, DB-per-tenant with a proxy that routes wire-protocol connections. Your app code doesn't change, you just connect to the proxy and it handles the rest. Sounds expensive operationally but it isn't if the orchestration is done for you. Worth looking into before you lock in.
If you are trully building this for internal use you should not worry about the scalabiltiy and for an ERP system you should not use Supabase. But if you are going to sell this as a service and lean towars multi-tenant architecture , consider phisical database isolation from the begining for every one of your customers.