Reactive Database That Absorbs the Server Layer

repotypescriptrustinfrastructuredatabasereal-timeself-hostedserverlessevent-bus

single reactive backend could unify Inngest durable functions + Redis state + real-time sync for joelclaw

Convex open-sourced their backend and made it self-hostable. The pitch: write pure TypeScript functions, get strong consistency, real-time reactivity, and serverless execution — all from one system. No separate database. No separate function runtime. No separate WebSocket layer for live updates. One binary does all of it.

The architecture is Rust under the hood with a V8 isolate layer for running TypeScript functions. Queries are reactive by default — clients subscribe and get automatic updates when underlying data changes. Mutations are transactional with strong consistency, not eventual. This is the database-as-backend pattern taken seriously: the data layer is the server layer. Jamie Turner and the Convex team have been building this since ~2022, and the self-hosted path works via Docker or a prebuilt binary. Plays well with Neon, Fly.io, Vercel, Netlify. There’s a generous free cloud tier, but the self-hosted route is what matters for sovereignty.

For joelclaw, this is a future exploration — not immediate. The current stack (Inngest for durable functions, Redis for state, Qdrant for vectors) works. But the idea of a single reactive system that handles server functions AND real-time data sync is worth tracking. Agent state that multiple clients need to observe simultaneously — gateway sessions, loop progress, memory queries — currently requires stitching together several services. Convex’s model collapses that into one thing. The Discord community has a #self-hosted channel that’s active, which is a good sign for long-term viability.

Key Ideas

  • Reactive queries as the default — clients subscribe to query results and get automatic updates when data changes, no polling or manual WebSocket wiring needed (docs)
  • Pure TypeScript server functions — queries and mutations are just TypeScript, executed in V8 isolates with strong consistency guarantees, not a bolted-on lambda layer
  • Rust backend, single binary — the crates/ directory is a serious Rust codebase covering database, isolate runtime, file storage, shape inference, and more
  • Self-hosting is a first-class path — Docker or binary, includes dashboard and CLI, not a “good luck” afterthought (self-hosting guide)
  • Database absorbs the server — no separate API layer, no separate function runtime, no separate real-time transport; the database IS the backend
  • Transactional mutations with strong consistency — not eventual consistency, not CRDTs, actual transactions across the whole dataset