Convex vs Supabase 2026: Backend Compared
TL;DR
Convex and Supabase are both "backend-as-a-service" platforms that handle your database, real-time, and serverless functions — but they take fundamentally different approaches. Supabase is open-source Postgres wrapped in Firebase-like tooling: familiar, self-hostable, and enormously adopted ($300M raised, $5B valuation by late 2025). Convex is a proprietary reactive database with a novel execution model: transactions are deterministic TypeScript functions, reactive queries are automatic, and there are no race conditions by design. Choose Supabase for a proven SQL foundation and self-hosting flexibility; choose Convex for a more opinionated full-stack TypeScript experience with zero boilerplate around real-time.
Quick Comparison
| Convex | Supabase | |
|---|---|---|
| Database model | Document + relational (custom) | PostgreSQL |
| Real-time | Built-in, automatic reactivity | Postgres Change Data Capture |
| Serverless functions | Mutations, queries, actions | Edge Functions (Deno) |
| Auth | Built-in (Clerk/Auth0 integration) | Built-in (GoTrue) |
| Storage | Built-in | Built-in (S3-compatible) |
| Self-hosting | No | Yes (open-source) |
| TypeScript support | First-class, end-to-end types | Generated types via CLI |
| Free tier | Generous (1M function calls/month) | Generous (2 free projects) |
| Paid plans start | $25/month | $25/month |
| Open source | No | Yes (Apache 2.0) |
Data Model and Real-Time
This is where the two platforms diverge most sharply.
Supabase sits on top of standard Postgres. Real-time is implemented via Postgres CDC (Change Data Capture) — you subscribe to changes on specific tables and Supabase streams them to connected clients. It works well but the data model is conventional SQL. You have full Postgres power: foreign keys, indexes, Row Level Security, full-text search, pg_vector for embeddings.
Convex uses a custom database with a document-ish data model (JSON documents in named collections, with optional schema validation). The real-time story is more elegant: any query function you write is automatically reactive. When the underlying data changes, Convex re-runs the query and pushes the updated result to subscribed clients. No manual subscription setup, no change streams to configure. The reactivity is a first-class property of the execution model, not an addon.
For apps that are heavily real-time — collaborative tools, live dashboards, multiplayer games — Convex's automatic reactivity is a significant DX advantage. For apps that are primarily CRUD with occasional real-time needs, Supabase's Postgres foundation is more flexible.
Serverless Functions
Supabase Edge Functions run on Deno. They're standard HTTP endpoints you can invoke from clients or use as webhooks. They're good for API routes, webhooks, and compute you need server-side, but they're relatively thin wrappers around Deno fetch.
Convex functions are more structured: mutations (writes), queries (reads, auto-reactive), actions (side effects, can call external APIs). The key property is that mutations are ACID-transactional by default, and Convex serializes concurrent writes automatically — no optimistic locking, no race conditions. This is a genuine advantage for collaborative or multi-user write scenarios that would require careful transaction management in Postgres.
The tradeoff is that Convex's execution model has constraints: mutations can't do I/O (no fetch calls), and actions that do I/O aren't automatically transactional. You need to learn Convex's model to use it correctly.
Auth
Both platforms include built-in auth, but their approaches differ.
Supabase Auth (GoTrue) is a full auth service: email/password, magic links, OAuth providers, phone OTP, MFA. It integrates tightly with Row Level Security so you can write policies like auth.uid() = user_id directly in Postgres. The auth system is self-hostable with the rest of Supabase.
Convex has built-in user identity tracking but typically delegates auth to Clerk, Auth0, or other providers via JWT integration. The integration is clean and idiomatic (one useConvexAuth() hook), but you're adding another service dependency. Teams already using Clerk often prefer this model; teams that want to minimize SaaS vendors might prefer Supabase's bundled auth.
Pricing
Both platforms offer a free tier that covers hobby projects and early development.
Supabase's free tier: 2 active projects, 500 MB database, 1 GB storage, 5 GB bandwidth. Paid plans start at $25/month per project with 8 GB database, 100 GB storage. Pricing is project-based and predictable for most apps.
Convex's free tier: 1M database transactions/month, 1M function calls, 10 GB storage. Paid plans start at $25/month with 25M function calls and higher storage. For write-heavy apps with many real-time subscribers, Convex costs can scale faster than Supabase.
Self-Hosting and Vendor Lock-in
This is a decisive factor for many teams. Supabase is fully open-source and self-hostable via Docker Compose or Supabase's own self-hosted distribution. If Supabase's pricing becomes untenable or the company changes direction, you can move your deployment on-premises.
Convex has no self-hosted option — it's a fully managed proprietary cloud. Your application logic is written against Convex's TypeScript API, which means migration to another backend requires rewriting your function layer. For teams with data residency requirements or strong vendor-risk policies, this is a hard constraint.
Background Jobs and Scheduled Functions
For applications that need work to happen outside the request/response cycle — sending emails, processing uploads, syncing third-party data, or running nightly reports — the two platforms take noticeably different approaches.
Convex has built-in scheduling with no external service required. You define recurring jobs using crons.interval() (run every N minutes/hours) or crons.cron() (standard cron expression syntax) directly in your Convex functions file. Background processing is handled via mutations and internal actions — you can queue work by calling an internal mutation that triggers an action, and Convex handles retries and ordering automatically. For most application-level scheduling needs, this is sufficient and the DX is clean: everything lives in TypeScript, everything has the same type safety as your regular Convex functions, and there is no separate queue service to configure or pay for.
Supabase relies on Postgres extensions and external services for background work. pg_cron is available in Supabase Postgres and handles recurring SQL-level tasks — refreshing materialized views, archiving old records, running maintenance queries. For more complex job orchestration (retries, fan-out, event-driven pipelines), teams typically reach for external services like Inngest or Trigger.dev, which integrate with Supabase via webhooks or database listeners. This is more flexible than Convex's scheduler — you can build arbitrarily complex job graphs — but it adds service dependencies and operational surface area.
The practical tradeoff: Convex's opinionated scheduler handles the common cases (send email after user signs up, run daily report, retry failed webhook) with minimal setup. Supabase's approach is more composable for complex workflows but requires more infrastructure decisions.
File Storage and Media Handling
Both platforms include file storage, but the implementations reflect their broader design philosophies.
Convex has built-in file storage with a direct-upload model: the client requests a signed upload URL from Convex, uploads directly to Convex's storage infrastructure, and the resulting file ID is stored as a field in your Convex database. Files are served via signed URLs with automatic CDN delivery. The storage is tightly integrated with the database — you can store file metadata alongside other document fields and query it with the same type-safe function API. The limitation is that Convex's storage is relatively opinionated: it's designed for straightforward file upload and retrieval, not advanced media processing workflows.
Supabase Storage is an S3-compatible object storage service. It supports public and private buckets, presigned upload and download URLs, and — importantly — image transformations via an integrated Imgproxy layer. You can request resized, cropped, or format-converted images on the fly through URL parameters without preprocessing files on upload. Row Level Security policies can be applied to storage objects, enabling the same fine-grained access control you use for database rows. Because the API is S3-compatible, existing tooling (like direct S3 SDK calls or CDN integrations) works with Supabase Storage with minimal changes.
For apps with straightforward file upload needs (profile photos, document attachments, user-generated media), both are adequate. For apps that need image transformation pipelines, public CDN delivery with access control, or migration from an existing S3-based setup, Supabase Storage's flexibility is a meaningful advantage.
When to Use Which
Choose Convex if:
- Building collaborative real-time apps where reactivity is core (not an addon)
- TypeScript full-stack and want end-to-end type safety with minimal boilerplate
- Willing to learn Convex's execution model for the DX benefits
- Vendor lock-in risk is acceptable for your use case
Choose Supabase if:
- You want a standard Postgres foundation you can query with any driver
- Self-hosting or data sovereignty is a requirement
- Need mature Row Level Security for multi-tenant apps
- Already using Postgres tooling and want a managed upgrade path
- Open-source alignment or exit options matter
For teams evaluating Supabase's database layer specifically, see Supabase vs Neon vs PlanetScale for a deeper comparison of the Postgres hosting market. If auth is a primary concern, read our OAuth2 vs API Keys vs JWT guide for the auth-specific tradeoffs that apply to both platforms. For ORM pairing decisions once you've chosen your backend, see Prisma vs Drizzle ORM.