Implemented
- Raft replication and durable storage
- TypeScript logic in isolated sandboxes
- Atomic mutations and reactive derived values
- Fresh reads and safe retries
- Live query watches over SSE
- Schemas, access checks and structured failures
- Timers, expiration, and work queues with fenced leases and retries
- Components, background tasks and triggers
- An in-process test database
- Durable indexes and incremental aggregates
- Membership changes and rolling upgrades
- Recoverable cross-group transactions
- Snapshots, recovery and tested leader failover
Know the edges
- Data is finite JSON
- Each indivisible piece of a rebuild must fit in one evaluation
- Callbacks are pure and synchronous; workers do the I/O
- A prepared cross-group transaction can block availability until it resolves
Plan around these:
- All live data stays in RAM. The published benchmark uses a small, hot dataset. It says nothing about capacity for large state.
- You set retention. Retry results are kept forever unless you opt into collecting them. Transaction history must be closed and collected explicitly. Jobs, timers and other finished records need their own cleanup.
- Writes to one database are ordered. Each logical database has one writer, so hot conflicting writes line up. Named partitions write independently.
- Keep host clocks in sync. Time comes from the serving node. A query can see a time that later appears to go backward after a leader change.
- No I/O in callbacks. They can't call out or keep module state between calls. Put external work in a queue and let workers do it.
Queue and size limits
There is no fixed limit on records, watches or operations per method. Time and memory budgets, queue sizes and JSON depth set the real limits; a very deep graph can hit the stack guard first. Full queues reject with 503. See the capacity settings and per-request limits.