Real-time sync, no drama.
One server. Every document, live.
The backend that makes the multiplayer real. It speaks documents, not rows — self-host the binary or let us run it for you.
One Tokio actor per document.
Each loaded document owns its own task. Updates arrive in batches of up to 100, flushed to SQLite every 100 ms, broadcast in ~1 ms.
- Zero locks — DashMap routes to the right actor.
- Up to 100 updates coalesced per SQL transaction.
- Broadcasts land on every connected client in under a millisecond.
- Auto-unload after 300 s idle — reloads on next update.
8 message types. One WebSocket.
Sync, Awareness, Auth, Subdoc, Stateless, Close, SyncStatus, QueryAwareness — all multiplexed over a single connection.
- VarInt / VarString wire format — compact and fast.
- Sync uses state vectors — only deltas cross the wire.
- Multiplex many docs over one connection.
- SyncStatus acks every applied update.
Six roles, resolved recursively.
Password or Ed25519 challenge-response. JWT in, effective role out — computed through the document tree with a recursive CTE.
- Passwordless by default — WebAuthn PRF compatible.
- Inheritance resolved down the parent chain.
- JWT 7-day (password) or 4-hour (crypto) TTLs.
- Device sessions + pairing invites for multi-device.
…valid 4hSQLite, or Postgres.
One sqlx-backed storage layer, two dialects. SQLite runs in WAL mode with concurrent readers and a serialized writer — one file, zero ops. Flip the URL to Postgres and writes fan out in parallel under MVCC.
- SQLite WAL mode — many readers, never blocked by writers.
- SQLite serializes writes — one writer at a time, engine-enforced.
- Postgres backend unlocks true parallel writes under MVCC.
- Flip the URL in
[database]— same schema, same API.
SHA-256 is the filename.
Content-addressed uploads deduplicate identical bytes automatically. Reference counts track liveness. Orphans are swept in the background.
- Same bytes, same blob — twice the refs, zero duplicate disk.
- Every file identifiable by its 256-bit hash.
- Orphan sweeper reclaims unreferenced blobs.
- Path traversal hardened at the storage boundary.
Thirty hooks. Native or Wasm.
Drop in custom logic at 30+ points across nine phases: server lifecycle, HTTP, auth, connections, documents, sync, permissions, uploads, snapshots.
- Native Rust via the Extension trait.
- Wasm components via wasmtime + WIT.
- before_update can transform updates in-flight.
- First error short-circuits the chain.
Spaces. Chat. Notifications.
Three first-class services on one stateless wire — a pinned hub space, persistent messaging, and notifications that issue themselves on mention. No extra endpoints, no add-ons to wire up.
- Every server has a hub — the pinned root space.
- Chat uses stateless frames — no extra endpoints.
- Notifications auto-issue on chat mentions.
- Seeded on boot from [[spaces.seed]].
One binary. Everywhere.
Linux · x86_64
single binary · ~14 MB
Linux · arm64
single binary · ~13 MB
macOS universal
single binary · ~15 MB
Windows · MSVC
single binary · ~14 MB
Start your own server.
curl -fsSL https://abr.ac/install.sh | sh, point your app at ws://localhost:3000/ws. That's it.