← All comparisons

Concile vs Supabase

Supabase is Postgres with services around it. Concile is one process with a reactive function layer. Different realtime models, different authorization, very different deploys.

Checked against Supabase's public docs and pricing on Mon Sep 21 2026. Spotted something out of date? Open an issue.

The short version

Side by side

ConcileSupabase
Live results from your own server codeYes, read-set precisePartly, row change events
Backend is plain TypeScript functionsYes, query, mutation, actionPartly, Edge Functions off to the side
Authorization is ordinary code, not a rules languageYes, functions you can unit testNo, row-level security in SQL
Self-host the whole productYes, one process, one commandPartly, several composed services
Single binary with no database to runYesNo, Postgres required
Swap the database without touching app codeYes, SQLite or PostgresNo, Postgres only
Durable workflows with rollbackYes, saga compensationNo, bring your own
Offline writes that survive a reloadYes, durable outboxNo
Full-text and vector searchNot built yetYes, tsvector and pgvector
Hosted cloudNoneYes
PriceFree to self-hostFree tier; Pro from $25 per month; Team from $599 per month; compute billed per project on top

Live query versus change feed

Supabase Realtime has three primitives. Broadcast is for messages between clients. Presence shows who is online. Postgres Changes streams row events off the database. A row event tells you a row changed. It does not tell you whether that row still belongs in the filtered, joined, or sorted list your screen shows. Anything beyond watching a whole table is the client's job to work out.

In Concile, the query is the subscription. The server records what the query read. It notices when a commit touches it. Then it re-runs the query and pushes the correct result. The client never re-derives anything. This is what realtime by default means.

Authorization: code versus SQL policies

Supabase authorization uses Postgres Row Level Security. These are policies written in SQL. You write one per operation per table. The database enforces them on every access. Supabase's own docs describe why this is hard to get right. A table in an exposed schema without RLS enabled is readable and writable by any role with a grant. Views bypass RLS unless security_invoker is set. Two tables with policies that reference each other raise a recursion error. Supabase recommends a pgTAP test file for each protected table. There is no other way to know the policies do what you meant.

In Concile, authorization is a function. It runs in the same transaction as the read or write. It is type-checked with the rest of your app. You unit test it like anything else. Row policies are available through @concile/authz if you want them composed for you.

Deploying it yourself

Supabase's core is open source. You can self-host it with Docker Compose or the CLI. This includes Studio. You run Postgres and the services around it. These services include PostgREST, pg_graphql, Realtime, GoTrue for auth, Storage, and Studio. Each one is a process you must keep alive and upgrade.

Concile is one process. Running docker compose up starts the engine, the database, and the dashboard. You can also run concile build to ship one executable. It runs on Cloudflare Workers too.

Where Supabase is ahead

Where Concile is ahead

Moving from Supabase

There is no migration tool because the model changes. Functions replace PostgREST calls and RLS policies. Your data remains portable. Export it from Postgres. Define the same tables in schema.ts. Import the data with concile migrate import. Each RLS policy becomes an if statement in the function that reads or writes that table. This is usually shorter than the policy was.

When to pick Supabase

You want Postgres and its ecosystem as the center of the system. You want a hosted product with regions and compliance today. You need built-in search. You are comfortable writing and testing SQL policies.

When to pick Concile

You want every screen to update on its own. You do not want to write invalidation logic. You want authorization you can read and test as code. You want a backend you can run as one process anywhere.