The Real-Time Database Problem
Firebase: no joins, no transactions, no relational queries. Supabase: real-time is an add-on. Building real-time from scratch: WebSockets, cache invalidation, conflict resolution.
Convex is a reactive database. Queries re-run automatically when data changes. Full ACID transactions. TypeScript end-to-end.
What Convex Gives You
Reactive Queries
// convex/messages.ts
import { query } from './_generated/server';
export const list = query({
handler: async (ctx) => {
return await ctx.db
.query('messages')
.order('desc')
.take(50);
},
});
// React component — auto-updates when data changes
import { useQuery } from 'convex/react';
import { api } from '../convex/_generated/api';
function MessageList() {
const messages = useQuery(api.messages.list);
return (
<ul>
{messages?.map(m => <li key={m._id}>{m.text}</li>)}
</ul>
);
}
No WebSocket setup. No polling. No cache invalidation. When someone adds a message, every connected client sees it instantly.
Mutations (ACID Transactions)
import { mutation } from './_generated/server';
import { v } from 'convex/values';
export const send = mutation({
args: { text: v.string(), author: v.string() },
handler: async (ctx, args) => {
await ctx.db.insert('messages', {
text: args.text,
author: args.author,
createdAt: Date.now(),
});
},
});
Server Functions (Actions)
import { action } from './_generated/server';
export const summarize = action({
handler: async (ctx) => {
const messages = await ctx.runQuery(api.messages.list);
const summary = await fetch('https://api.openai.com/v1/chat/completions', {
body: JSON.stringify({ messages: [{ role: 'user', content: messages.map(m => m.text).join('\n') }] }),
});
return summary;
},
});
Scheduled Functions
export const cleanup = mutation({
handler: async (ctx) => {
const old = await ctx.db.query('messages')
.filter(q => q.lt(q.field('createdAt'), Date.now() - 86400000))
.collect();
for (const msg of old) {
await ctx.db.delete(msg._id);
}
},
});
// Schedule: ctx.scheduler.runAfter(3600000, api.messages.cleanup);
Free Tier
- 1M function calls/month
- 1GB database storage
- 1GB file storage
- Real-time sync included
Why This Matters
Real-time shouldn't be hard. Convex makes every query reactive by default, so you build real-time apps without thinking about real-time infrastructure.
Need real-time web data? Check out my web scraping actors on Apify Store — data feeds for your reactive apps. For custom solutions, email spinov001@gmail.com.
Top comments (0)