voidbase compared to Convex
These two disagree about where your backend code lives. Convex says you write functions and it runs them. voidbase says you get an API, and you write code only where the API is not enough.
| voidbase | ||
|---|---|---|
| Day one | A working CRUD API, auth, files and an admin panel before you write anything. | Nothing until you write the functions. |
| How the client reads data | A generated REST API over your collections, with filters and relations. | TypeScript query functions you write, called by name. |
| Realtime | Subscribe to a collection. You decide what to do with a change. | Every query is reactive and recomputes when its inputs change. |
| Types | The SDK is typed, but not from your collections. A generated client is planned. | End to end TypeScript. A rename breaks the build. |
| Transactions | None today. Writes validate, then run as one atomic batch. | Real, and the mutation model is built on them. |
| Changing the schema | In the panel, live, with no deploy. | A code change and a deploy. |
| Non-developers | Can edit content in the admin panel. | Everything is code. |
| Where it runs | Your Cloudflare account, every region. | Their cloud, or a backend you host yourself. |
| Cost when idle | Nothing. | Free tier, then usage. |
in your favour not yet, and on the roadmap against you depends what you are building
What Convex does better
Reactivity, done properly. A query is a function, Convex tracks what it read, and when any of that changes it recomputes and pushes the new result. You never write subscription logic or work out which events invalidate which screen. voidbase gives you record-level subscriptions and leaves the rest to you.
Types all the way through. Your schema, your functions and your components share one TypeScript definition, and a rename breaks the build. voidbase's collections are data, edited at runtime, so a rename breaks at the call instead.
And transactions. Convex mutations are transactional by design, which removes a class of bug that voidbase's batch model can only mostly remove.
What voidbase does better
You start with a backend rather than a blank file. Collections, an API, auth, file handling and an admin panel are there before you write a line.
The schema changes without shipping code. Add a field in the panel and it is live. In Convex that is a code change and a deploy, which is right for some teams and wrong for a content-shaped app.
And the account is yours from the first command, with the database and the files in it, on infrastructure whose pricing page you can read.
Pick Convex if
You are building a TypeScript app where most screens are live views of changing data, and you would rather write functions than model collections.
Pick voidbase if
You want a working backend on day one, an admin panel other people can use, and a schema that is data rather than code.
What it costs
Move the sliders to your own traffic. Both columns are computed from published list prices, and every assumption behind them is in the panel at the bottom of this section.
voidbase, on your own Cloudflare account
$9.79/month
Workers Paid, D1, R2, Durable Objects
- Workers Paid basethe account minimum
- $5.00
- Requests21.0M, 10M included
- $3.30
- CPU time3ms a request
- $0.66
- Database rows80M read, 3.0M written
- $0.00
- Database storage1.5 GB, 5 GB included
- $0.00
- File storage50 GB in R2, egress free
- $0.75
- Realtime fanout1.5M durable object requests
- $0.08
No per-user charge: signing in is an ordinary request, so monthly active users do not appear at all. Durable object compute is left out, because a hibernating connection bills none.
The same app on Convex
$39.16/month
Professional
4.0× the voidbase bill
- Professional baseone developer
- $25.00
- Function calls22.5M including 1.5M reactive re-runs, 25M included
- $0.00
- Database storage1.5 GB, 50 GB included
- $0.00
- File storage50 GB, 100 GB included
- $0.00
- Data egress168 GB, 50 GB included
- $14.16
Reactive re-runs are counted as function calls, which is the assumption most likely to be wrong here and the one that decides this column: Convex may well batch or dedupe them. Query and mutation compute is free on this plan, and database bandwidth and action compute are not modelled. Convex bills per developer, so a team of five starts at five times the base.
Model assumptions and sources
An estimate whose assumptions are hidden is an advertisement. This one assumes each API read or write is one Worker request; a read touches about 4 SQLite rows with a relation expanded and a write about 3; a request costs about 3ms of CPU, measured on this site's own instance; each realtime connection receives about 50 pushed updates a day; and a response is about 8KB where a plan bills bandwidth. A WebSocket connection is billed as one request and the messages over it are not, and a hibernating connection bills no compute. Monthly active users are an authentication headcount: voidbase has no per-user charge at all, because signing in is an ordinary request.
Rates as of 8 September 2026, from Workers, D1, R2, Durable Objects and convex.dev/pricing. Both columns are estimates. Measure before you commit either way, and tell us if a number here is wrong.
And what about speed?
Everything below this line is guesswork. We have not benchmarked these systems against each other, and we are not qualified to do it well. Doing it properly means controlled hardware, representative workloads, warm and cold paths measured separately, percentiles rather than averages, and somebody who has done it before checking the method. None of that happened here.
What follows is arithmetic over round numbers we believe are roughly right. It is here to give a rough shape of the trade to someone who wants one, and to annoy someone who knows better into correcting us. The numbers being multiplied are listed underneath so you can argue with a specific one. Do not choose a backend on this section.
What we think the trade is
| voidbase | Convex | |
|---|---|---|
| Where the code runs | Every Cloudflare location, so near the user by construction | The one region you chose |
| Where the database is | A network hop from the code, which is the slow part above | Beside the code, so queries are quick |
| A user far away | Pays about the same as one nearby | Pays the full round trip, on every call the page makes |
| Cold start | Milliseconds: an isolate, not a container | Hundreds of milliseconds if it scaled to zero |
| Ten times the traffic | Same latency, more instances. Nothing to do | A bigger instance, and somebody to notice |
| A hundred times the traffic | Same again. The limit is your database, not the runtime | Read replicas, connection pooling, sharding |
| Realtime transport | One hibernating socket per client, held by a durable object | Reactive queries: the server recomputes and pushes, which is more than a subscription |
| Realtime fanout | ~8 ms to 1k subscribers | ~8 ms to the same |
| Subscribers before it hurts | Per instance, and the object hibernates when quiet | Bounded by the instance, and usually billed as well |
| Idle | Costs nothing and runs nothing | The instance runs anyway |
| What gives way first | Database throughput, or one instance's own durable object | The instance, and then the database behind it |
Their cloud, with the database beside the functions.
The numbers being multiplied
Correct one of these and the bars move. Reaching a Cloudflare edge location, 15ms. A Worker starting cold, 5ms, because an isolate is not a container. A container waking, 900ms. One D1 query from a Worker, 25ms. One query to a database beside the code, 3ms. One query to SQLite on the same disk, 1ms. The handler itself, 4ms.
The one we are least sure of is the D1 number, and it is the one that decides whether the first bar beats the second. It is also the one most likely to change: putting an instance's data in a durable object beside its own code would replace that network hop with a local read.
Please prove us wrong
If you benchmark backends for a living, we would rather publish your method and your results than our arithmetic. Open an issue on the repository with what you would measure and how, and we will run it, publish whatever it says, and replace this section with it.
Fix it yourself. The link below opens this file in GitHub's editor and forks the repository for you if you need one, and your change becomes a pull request without leaving the browser.