Supabase is Postgres with auth, storage, realtime, and edge functions wrapped around it. Firebase is a document store with an unusually good mobile SDK. The choice mostly comes down to whether your data is relational and whether you will ever need to leave. For most application data Postgres wins; for mobile-first apps needing offline sync, Firebase still does something Supabase does not match.
Side by side
| Supabase | Firebase | |
|---|---|---|
| Data model | Relational (Postgres) | Documents |
| Queries | Full SQL, joins, aggregates | Limited; denormalise instead |
| Authorisation | Row-level security in the database | Security rules in a separate language |
| Migrations | Real, versioned, reviewable | Ad hoc |
| Offline sync | Not really | Excellent |
| Mobile SDKs | Good | Very mature |
| Portability | It is Postgres; you can leave | Proprietary |
| Cost shape | Compute and storage | Per read/write — can surprise you |
The real argument is relational
Almost every business application is relational whether or not you admit it up front. A workspace has members, members have roles, roles grant permissions, records belong to a workspace and are assigned to a member. That is a graph of foreign keys.
In Postgres you express it directly and the database enforces it. A row cannot reference a workspace that does not exist, because a constraint forbids it. In a document store you denormalise, and then you own the consistency problem forever: the same fact is stored in four places and it is your job to keep them agreeing.
The second-order effect is the one that gets you. Denormalised data makes new questions expensive. Someone asks for a number nobody planned for — usage by role, by month, excluding trials — and in SQL that is a query, while in a document store it is a migration and a backfill.
Constraints, joins, and transactions are not academic preferences. They are the difference between the database refusing bad data and you discovering it in a support ticket.
Row-level security: the best and worst part
Supabase’s authorisation model puts access rules in the database. A policy decides which rows a given user can see, and it applies no matter which client asks. That is the correct place for it: authorisation enforced in one layer that nothing can route around.
It is also where I have made the most mistakes, so here is what actually bites.
A new table is not protected until you protect it. Creating a table and enabling RLS with no policies is not a safe default in the way you might hope, and default grants can expose a table you assumed was private. Do not reason about this from memory. Query the table as an anonymous user and see what comes back. That test takes a minute and is the only thing I now trust.
Views can bypass your policies. A view does not automatically inherit the row-level security of the tables underneath it, which means a carefully secured table can leak through a convenience view built on top. Check every view separately.
Some operations need more grants than you expect. An upsert, for example, needs insert permission even when it usually updates. The failure appears at the worst time, in production, on the path you tested least.
None of this is an argument against RLS. It is an argument for verifying it empirically rather than by reading your own policies and nodding.
Where Firebase still wins
Being fair, because I would still pick it for some things.
Offline-first mobile. Firebase’s local persistence and sync are genuinely excellent and largely invisible to you as a developer. If your users are on trains, in basements, or in the field, this is not a small convenience — it is most of the product. Supabase does not match it.
Mobile SDK maturity. Years of edge cases handled, and a great deal of documentation and community answers for the specific problem you are hitting at 11pm.
Genuinely document-shaped data. If your records really are self-contained blobs with no meaningful relationships, the relational argument evaporates and you are just choosing a store.
Push, analytics, crash reporting in one place. The wider platform is a real advantage for a mobile team that wants one vendor.
The cost shape
Different enough to matter architecturally, not just financially.
Firebase charges per read. That is fine until a screen displaying a list of items does a read per item, and a busy page becomes a per-visit cost. It also quietly pushes you toward denormalising further, which is a data model decision being made by a pricing page.
Supabase charges roughly for compute and storage. A query returning a thousand rows costs about what a query returning ten does. That means you optimise for correctness and only then for performance, which is the right order.
Neither is universally cheaper. The point is that one of them lets your billing model influence your schema.
How I choose
- Relational data, web or web-plus-mobile? Supabase.
- Offline-first mobile app? Firebase, and it is not close.
- Might you need to leave? Supabase. It is Postgres, so exit is a dump and restore rather than a rewrite.
- Do you need reporting? Supabase. SQL against your live schema beats exporting to a warehouse to answer a simple question.
- Already shipped on Firebase and it works? Stay. Migrating between a document model and a relational one is real work and needs a real reason.
Practical notes
- Verify RLS as an anonymous user. Every table, every view, after every migration. This is the single highest-value habit here.
- Keep migrations in version control and treat them as code that gets reviewed. The dashboard is convenient and undoes that discipline.
- Free-tier projects pause. Fine for a prototype, not for anything a client will open.
- Deploy edge functions one at a time when you have a lot of them. Batch deploys fail in ways that are unpleasant to untangle.
- Do not put business logic only in the client. With RLS the database is your last line of defence; keep it authoritative.
FAQ
Is Supabase better than Firebase?
For relational application data, usually — real queries, joins, constraints, and migrations. Firebase wins on mobile SDK maturity and offline sync.
Is Supabase really open source?
The core is, and it is Postgres underneath, so your data stays portable. That matters most on the day you want to leave.
What is the biggest gotcha?
Row-level security. A new table is not protected until you write policies, views can bypass them, and default grants can expose more than you expect. Verify as an anonymous user.
Should I migrate from Firebase?
Only for a concrete reason, usually queries you cannot express or read costs that scale badly. A working app is not a problem to solve.
Related: Postgres row-level security, practically, Supabase edge functions vs Vercel functions, and how I build web apps.