What is Convex? A plain explanation for developers
By Gerald · 8 June 2026
Most backend tutorials assume you want to build a REST API, manage cache invalidation, and wire up websockets yourself. I did not want to do any of that when I started building Flow. I wanted screens to update automatically when data changed, and I wanted the entire stack to speak TypeScript.
That is what Convex is built for. It is a reactive backend: a database plus server functions where queries automatically push new results to the client when the underlying data changes. You write backend logic in TypeScript, call it from React or another frontend, and the live updates happen without you building a separate realtime layer.
Convex is a backend for developers who would rather write product logic than plumbing. It is not SQL, it is not Postgres, and it is not a generic cloud database. It is an opinionated application backend that happens to include its own document-relational database.
What Convex actually gives you
Convex bundles four main pieces into one platform.
A document-relational database
Convex stores data in tables, but the rows are JSON-like documents rather than rigid SQL rows. You can define schemas, create indexes, and query by fields, owners, dates, and relationships through document IDs. It is not a schemaless NoSQL store, but it is also not a traditional relational database. The documentation calls it a document-relational database because you get some relational behavior, like indexes and one-to-many references, without writing SQL joins.
Schemas are written in TypeScript and validated at deploy time. You define the shape of your documents, mark fields as required or optional, and create indexes for the queries you actually run. If you change a schema, the CLI warns you about incompatible data. That discipline catches mistakes early without forcing you into a rigid migration workflow.
Reactive queries
This is the feature that defines Convex. When you write a query function in TypeScript and call it from the client, the client subscribes to the result. Convex tracks which documents and indexes that query depends on, and when any of them change, it pushes the updated result to every connected client automatically.
You do not write websocket handlers. You do not invalidate caches. You do not decide when to re-fetch. The screen stays current because the backend tells it to.
For example, if your query loads all tasks for the current user sorted by due date, Convex knows that any new task, deleted task, or changed due date for that user affects the result. When one of those changes happens, every client running that query receives the updated list. You wrote one function. The live behavior came with it.
Mutations
Mutations are TypeScript functions that run on the server and can read and write data. They are transactional by default. If a mutation touches several records, all of those changes succeed together or fail together. Convex handles concurrency through its transaction model, so race conditions inside a mutation are harder to create by accident.
You define who can call a mutation through authentication checks inside the function itself. The pattern is straightforward: verify the user, validate the input, read what you need, write what you changed. Because mutations and queries live in the same TypeScript project, you can share validation logic and types without maintaining separate packages.
Actions
Actions are server functions that can call external APIs, send email, or perform other side effects. Unlike mutations, actions are not transactional and can run longer. They are useful for integrating with third-party services without leaving the TypeScript backend.
A common pattern is to use a mutation for the database change and an action for the side effect. The mutation stays transactional and fast. The action handles the slow or unreliable external call. If the action fails, you can retry it without rolling back the database write.
How the developer experience feels

The Convex CLI generates TypeScript types from your backend functions. When you change a query argument, your React code shows a type error immediately. There is no separate OpenAPI spec to maintain, no GraphQL type generation step, and no runtime API client to update by hand.
Local development runs a full Convex backend on your machine. You start the dev server, write a function, and the client picks up the new types automatically. Deployment is a single command that pushes your functions and schema to the hosted service. Rollbacks and function versioning are handled by the platform.
That tight loop matters. When the distance between a frontend button and the backend function it calls is short, you move faster. When the types flow through automatically, you break things less often.
How Convex compares to what you might already know
Convex vs Firebase
Firebase also offers realtime data. The difference is type safety and architecture. Firebase stores JSON documents in a flexible tree structure, and its realtime sync is powerful but loosely typed. Convex gives you TypeScript functions with generated API types, schema definitions, and a structured table model. Firebase has a mature ecosystem and broader platform support. Convex has tighter type integration and a more modern function-based backend model.
If you already know and trust Firebase, Convex is not a mandatory upgrade. If you are starting a new TypeScript app and want type safety across the entire stack, Convex is a cleaner fit.
Convex vs REST APIs
A traditional REST backend requires you to define endpoints, serialize data, handle cache invalidation, and decide when the client should refresh. With Convex, there are no endpoints to maintain. The client calls typed functions directly. When data changes, every subscribed query updates automatically.
The tradeoff is that you give up the universal simplicity of HTTP. Every client must use the Convex client library. For a product built in React or React Native, that is usually fine. For a public API that needs to serve arbitrary consumers, REST or GraphQL still makes more sense.
Convex vs traditional SQL databases
PostgreSQL and MySQL are excellent databases. They are mature, widely understood, and supported by decades of tooling. But they are not reactive by default. If you want live updates from a SQL database, you build it yourself: polling, logical replication, change data capture, or a separate realtime service.
Convex gives you reactivity out of the box, but you lose SQL, standard database clients, and the entire ecosystem of Postgres extensions and reporting tools. You model data around Convex queries and indexes rather than joins and views.
When Convex is the right choice
Convex fits well when:
- Your app is built in TypeScript, especially React or React Native.
- Live screens are central to the product experience.
- Your queries load records by known indexes rather than complex ad-hoc joins.
- You want backend functions and database logic in the same language as your frontend.
- You prefer an opinionated platform that makes decisions for you.
I use Convex for Flow because notes, tasks, captures, and reminders all need to stay in sync across devices without me managing websockets or cache logic. When you move a task to a new column on one device, every other open screen sees the change immediately. That behavior is part of the query model, not a feature I added later.
The honest limitations
Convex is not the right backend for every project.
It is not SQL. If your product depends on complex relational queries, reporting, or existing database tooling, you will fight the platform rather than working with it.
The ecosystem is smaller than Postgres. There are fewer Stack Overflow answers, fewer third-party integrations, and fewer hiring candidates who already know it.
It is vendor-specific. While Convex publishes its backend as open source and supports self-hosting, moving an app off Convex means rewriting queries, mutations, and reactive logic around a different data layer. The data can be exported. The app logic cannot.
The pricing model also shifts at scale. The free tier is generous for development and small products, but production usage with many function calls or stored data moves into metered costs that can surprise you if you do not model your usage carefully.
Who should skip it
- Teams that need complex SQL reporting or analytics
- Products that expose a public API to diverse clients
- Builders who want maximum database portability
- SQL-first teams that already have strong operational experience with Postgres
Frequently asked questions
What is Convex used for? Convex is used for building reactive TypeScript applications where backend data needs to stay synchronized with frontend screens automatically. Common use cases include productivity apps, live dashboards, collaborative tools, and real-time games.
Is Convex free? Convex offers a free tier for development and small projects. Production use moves into paid plans based on usage. Check the current Convex pricing page for exact quotas and rates.
Does Convex use PostgreSQL? No. Convex uses its own document-relational database and query engine. It is not built on PostgreSQL, MySQL, or any other standard SQL database.
Is Convex self-hosted? Convex offers a hosted service by default. The backend is also available as open source with self-hosting instructions, though running it yourself requires operational effort.
How does Convex compare to Firebase? Both provide realtime data, but Convex offers stronger TypeScript integration, typed backend functions, and a more structured database model. Firebase has a larger ecosystem and longer track record.
Related reading
- Convex review: a backend that stays out of your way
- Convex vs Supabase: which backend is better for you?
- How self-hosted note-taking works without running a server
- Why I built Flow
Pick Convex when reactivity and TypeScript integration matter more than SQL compatibility and database ecosystem breadth.
If you are building a reactive TypeScript app and want to spend less time on backend plumbing, try Convex on its free tier and see whether its defaults fit your product. The worst outcome is that you learn exactly what tradeoffs you care about.