One Supabase project or one per app?
One project with a schema per product is a production choice, not a free-tier workaround. Here is the structure, the dated bill, and the four places it stops working.
· 7 min read
One project, with a schema per product. It is a production architecture rather than a way to stay on the free tier, and I say that from a portfolio of seven live products that share a single paid Supabase project, not from a weekend experiment.
That answer is worth stating plainly because almost every version of this question gets answered the other way. The usual reply is that one project per app is the correct isolation boundary and consolidating is something hobbyists do to avoid paying. I ran it the usual way first, with one project per product, and moved off it deliberately on 3 July 2026.
What the usual advice gets right
One project per app really is the simplest thing that works, and if you have one product it is obviously correct. The isolation argument is also real: separate projects mean separate credentials, separate data, separate blast radius. I am not going to pretend those disappear.
What the advice misses is that the isolation you get is per project, and the cost you pay is per project, and only one of those two scales with anything you care about. Users, traffic, and data are the things that should drive a database bill. The number of ideas you have had is not.
What I actually changed
Four Supabase projects became one project with a schema per product.
Inside the single project, separation is by schema rather than by a product column on shared tables. A core schema holds what is genuinely shared across the portfolio: organizations, members, domains, brands, billing accounts, subscriptions, audit events, AI usage. Each product then owns a schema for its own tables.
Tenancy is org-scoped row level security built on a few shared helpers, so that being signed in grants nothing on its own. A request has to belong to an organization that owns the row. Users of one product never bleed into another because no policy anywhere is satisfied by authentication alone.
The schema boundary is doing real work, and it is worth being specific about which work. It is not a security boundary; row level security is. It is an extraction boundary. Pulling one product out later is closer to dumping one schema than to filtering every table in the database by a column. That distinction is the whole reason not to pool everything into shared tables with a product discriminator, which is the shortcut this pattern invites.
The bill, with the date on it
Four projects cost $59.74 in the month before I consolidated. One project costs $25.
I am putting the number late and small on purpose, because nobody's portfolio is failing over $35 a month, and if the bill were the argument then the argument would be weak. It is here because a claim like this is worthless if the numbers are decorative.
The mechanism matters more than the total. Supabase Pro is $25 a month and includes a $10 monthly compute credit that covers one Micro instance. One project, credit applied, $25. Every additional project brings its own compute charge, and the credit covers only the first. So the bill was scaling with a number I had picked casually, one afternoon, ten seconds at a time.
I stayed on Pro rather than dropping to Free, deliberately. Free has no daily backups and there is real customer data in there. Consolidating is about paying for something once. It is not about paying nothing.
The part nobody warns you about
The money was the smallest of it.
Four projects had quietly become four of everything around them: four sets of keys across four env files, four auth redirect allowlists to keep in step, four migration histories, and four places a schema change could be half applied. None of that is visible on the day you create the second project, which is exactly what makes it worth saying out loud.
The redirect allowlist is the one that bites hardest, and it bit me again as recently as last week on a product I had just added. Supabase silently rewrites a redirect URL it does not recognise back to the project's Site URL. Miss one host and that product's sign-in and confirmation emails deliver users to a different product's site, with no error anywhere to tell you. One project does not remove that list. It does mean there is exactly one of it.
The alternative I priced and rejected
I looked hard at Neon, which is cheaper Postgres, and for a couple of weeks I had a plan to move.
I did not move, because my apps do not use Postgres. They use Supabase. Authentication is Supabase Auth, every row level security policy is built on the auth.uid() it provides, and a good deal of the data access goes through PostgREST. Swapping the database engine would have meant rebuilding the auth system and rewriting every policy, then owning both of those forever, to save less per month than the migration would have cost me in a single evening.
Cheaper Postgres is only a drop-in replacement if what you were using was Postgres. That comparison turns up in every thread on this topic, always on price per gigabyte and never on what you would have to rebuild.
Where this stops working
It does stop. Four places, and I would leave at any of them.
One database is one blast radius. A bad migration, a runaway query, or a paused project takes every product down together. I reduce the odds with CI-only migration deploys and a local integration suite that has to be green before a migration-touching push lands. Neither changes the radius.
One team is one permission set. Anyone you add so they can ship a fix to one product can see and deploy all of them. There is no polite way to give a contractor access to product three only.
Compliance is where you should leave. If a product needs SOC 2, HIPAA, or anything with an auditor attached, the audit scope is the system boundary, and sharing a database with five unrelated products makes that boundary your entire portfolio. Pulling it out into its own project is cheaper than certifying everything else by accident.
Selling is the other place you should leave. A buyer wants a clean asset. The schema boundary is what makes that a described piece of work rather than an archaeology project, but it is still work.
So which should you do
If you have one product, one project. The question does not arise and consolidating a portfolio of one is not a thing.
If you have several and they are all still ideas, one project with a schema each, and stay on a paid plan if any of them has data you would be upset to lose.
If one of them grows into something with an auditor, a buyer, or a compliance questionnaire, take that one out. Being able to leave cleanly is the point of the schema boundary, and using it is not an admission that the pattern failed.
The full operational version of this, covering the other vendor accounts, the entity, and what I would do differently, is in running many products. The architecture is in architecture, and the cloud setting people miss when they consolidate, the exposed schemas list, is in deploying.