Supabase vs Convex - SQL Database or Reactive TypeScript?

Supabase vs Convex is a choice between two programming models. Supabase is Postgres: you design tables, query with SQL or a generated REST API, and protect rows with policies. Convex is a reactive database where your backend is TypeScript functions running inside it; queries re-run automatically and every client stays in sync without writing any subscription code. Pick Convex for highly interactive TypeScript apps where live updates are the product. Pick Supabase when you want SQL, standard Postgres tooling, reporting and an exit path to any Postgres host.

Neither is a drop-in replacement for the other. Moving between them means rewriting your data layer, so it's worth deciding carefully.

#The models side by side

SupabaseConvex
DatabasePostgresDocument-relational (JSON-like documents, references by id)
Query languageSQL; REST and GraphQL generated from the schemaTypeScript query functions, no SQL
WritesSQL, REST, RPC to Postgres functionsMutation functions, each a transaction
TransactionsPostgres (READ COMMITTED default, SERIALIZABLE available)Serializable with optimistic concurrency, automatic retries
RealtimeSubscribe to Postgres changes, broadcast, presenceEvery query is live; clients update automatically
Side effectsEdge Functions (Deno)Actions (can call external APIs)
Access controlRow Level SecurityChecks in your functions
Self-hostingDocker ComposeOpen-source backend, FSL Apache 2.0 license

#How Convex works

From Convex's docs: Convex is "the open source, reactive database where queries are TypeScript code running right in the database." There are three kinds of functions:

  • Queries read data, can't make network requests, and are reactive: "Whenever any data on which a query depends changes, the query is rerun, and client subscriptions are updated."
  • Mutations read and write; "the entire Convex mutation function is a transaction," with serializable isolation and automatic retries on conflict.
  • Actions can call third-party APIs (an LLM, an e-mail service) and reach the database only through queries and mutations.

On the client, a React hook subscribes to a query and re-renders when the result changes. There's no cache to invalidate and no websocket code to write. That's Convex's big selling point, and it's real.

#How Supabase works

You define tables in SQL and get APIs from the schema:

SQL
create table public.messages (
  id bigint generated always as identity primary key,
  room_id bigint not null,
  author_id uuid not null default auth.uid() references auth.users,
  body text not null,
  created_at timestamptz default now()
);
alter table public.messages enable row level security;
create policy "Room members read" on public.messages for select to authenticated
  using (room_id in (select room_id from public.room_members where user_id = auth.uid()));

Reading and listening on the client:

JavaScript
const { data } = await supabase
  .from('messages').select('*').eq('room_id', 42).order('created_at')

supabase.channel('room-42')
  .on('postgres_changes',
    { event: 'INSERT', schema: 'public', table: 'messages', filter: 'room_id=eq.42' },
    (p) => append(p.new))
  .subscribe()

More code than Convex for the live part. In exchange, the same table works with any SQL client, BI tool, ORM or pg_dump.

#Where each model shines

Convex is a strong fit for:

  • Collaborative apps (whiteboards, docs, multiplayer games) where everything on screen must stay live.
  • Teams that are TypeScript end to end and don't want to context-switch to SQL.
  • Apps whose logic is mostly "on this event, update these documents", which fits mutations well.

Supabase is a strong fit for:

  • Relational data with reporting needs: "revenue by plan by month" is one SQL query.
  • Apps that need Postgres extensions: pgvector, PostGIS, full-text search, cron.
  • Teams that want the database usable from many tools and languages.
  • Anyone who wants to be able to take the database to another host.

#Security model

In Convex you check permissions inside each function, for example by reading the user's identity and verifying they belong to a room. It's ordinary code, easy to read and test.

In Supabase, policies live in the database and apply to every API path. One policy protects REST, GraphQL, Realtime and any future client. The risk is the inverse: forgetting to enable RLS on a new table leaves it open, so check the security advisor.

#Pricing, as of November 2026

Convex (pricing):

Free & StarterProfessional
Price$0, pay as you go$25 per developer/month
Function calls1M included, then $2.20 per 1M25M included, then $2 per 1M
Database storage0.5 GB, then $0.22/GB50 GB, then $0.20/GB
Bandwidth1 GB, then $0.132/GB50 GB, then $0.12/GB
File storage1 GB100 GB

Supabase (pricing): Free with 500 MB database, 1 GB storage, 5 GB egress, 50,000 MAU, 2 active projects, paused after a week of inactivity. Pro from $25/month per organization (not per developer) with 8 GB disk, 100 GB storage, 250 GB egress and 100,000 MAU.

The key difference: Convex's paid plan scales with the number of developers; Supabase's with resources and projects. A team of four on Convex Professional is $100/month before usage. A team of four on Supabase Pro is $25 plus compute.

Also note Convex counts function calls. Reactive queries re-run when data changes, so a busy collaborative screen with many subscribers can use a lot of calls. Model it with your real traffic.

#Lock-in and exit paths

Convex's backend is open source under the FSL Apache 2.0 license, which converts each release to Apache 2.0 after two years, and it can be self-hosted (self-hosting). Your code, however, is written against Convex's function model; moving to another database is a rewrite.

Supabase data is standard Postgres. Moving to another Postgres host is a dump and restore, and moving to another Supabase-compatible platform keeps your client code too.

#Where StitchDB fits

StitchDB is a hosted Postgres backend that speaks the Supabase APIs, so the Supabase side of this comparison applies to it as well (compatibility). Two of its features narrow the gap with Convex's developer experience:

  • Offline sync: stitchdb.offline({ tables: ['todos'] }) keeps tables on the device, subscribe() re-renders on changes, and writes queue offline with a conflict rule per table.
  • Collaborative documents and realtime message history, so reconnecting clients get missed broadcasts in order.
JavaScript
const db = stitchdb.offline({ tables: ['todos'] })
await db.ready
const stop = db.table('todos').subscribe((rows) => render(rows))

It's priced per account, not per developer: Pro is $15.99/month with 10 team members. The trade-offs: EU-only hosting (Germany and Finland), a younger platform, no self-hosted edition, and it's still SQL and policies at heart, not Convex's all-TypeScript model.

#Who should pick what

  • Pick Convex if live, collaborative UI is the core of your product and your team prefers TypeScript to SQL.
  • Pick Supabase if your data is relational, you need SQL and extensions, and you want a portable database with worldwide regions.
  • Pick StitchDB if you want the Supabase model hosted in the EU with built-in offline sync and per-account pricing.

More comparisons: Convex alternatives and the best backend as a service platforms.

#FAQ

#Is Convex better than Supabase for realtime?

For automatic live queries, yes: every Convex query is reactive by default. Supabase gives you change streams you subscribe to and handle yourself.

#Can I use SQL with Convex?

No. Convex queries are TypeScript functions. Its docs say there is no SQL to write.

#Is Convex open source?

The backend is open source under the FSL Apache 2.0 license and can be self-hosted.

#Which is cheaper for a team?

Supabase Pro is priced per organization ($25/month base); Convex Professional is $25 per developer per month, as of November 2026.

Want Postgres with live, offline-ready tables? Try StitchDB free.