Realtime
vb.subscribe(collection, filter, cb) opens a long-lived realtime
connection and routes server events to your callback. Backed by a
WebSocket where supported, with automatic SSE fallback for environments
that can’t open WS (some serverless platforms, certain corporate
proxies).
Subscribe to all events
Section titled “Subscribe to all events”const off = vb.subscribe("posts", "*", (ev) => { console.log(ev.action, ev.record); // ev.action: "create" | "update" | "delete" // ev.record: T (typed via Schema generic)});
// later, drop just this subscription:off();Filter to a single record
Section titled “Filter to a single record”vb.subscribe("posts", "p_42", (ev) => { // only fires for record id = "p_42"});Filter via expression
Section titled “Filter via expression”Pass the same expression-language filter you’d use in list:
vb.subscribe("posts", { filter: "author = @request.auth.id" }, (ev) => { // only fires for events on records you own});The server applies your auth + the collection’s view_rule BEFORE
broadcasting, so users never see records they couldn’t GET.
Multiple subscriptions
Section titled “Multiple subscriptions”const offPosts = vb.subscribe("posts", "*", onPost);const offUsers = vb.subscribe("users", { filter: "verified = true" }, onUser);
// Disconnect the realtime channel entirely (keeps auth):vb.closeRealtime();A single WS connection is shared across all vb.subscribe calls — the
manager multiplexes topic subscriptions over the same socket.
Auth + reconnect
Section titled “Auth + reconnect”The connection authenticates with the same token from vb.client.authStore.
Token expired → auto-refresh runs once, the WS reconnects, subscriptions
re-arm. Token refresh fails → all subscribers receive a final close
event and the connection stays down until the next subscribe call.
vb.realtime.on("status", (s) => { // s: "connected" | "reconnecting" | "closed"});Backoff: 1s, 2s, 4s, … capped at 30s. Reconnect retries forever; cap
yourself with vb.closeRealtime() if the user logs out.
SSE fallback
Section titled “SSE fallback”If WebSocket opens fail (handshake or auth), the SDK falls back to
server-sent events at GET /api/v1/realtime + POST /api/v1/realtime
for subscription updates. The same subscribe API works either way —
your code doesn’t change.
Topic shape
Section titled “Topic shape”Events on the wire:
{ "topic": "posts", "action": "create", "record": { "id": "p_42", "title": "hi" }}For the wildcard * subscription, every collection’s events come
through the same callback — switch on ev.topic if you need to
disambiguate. See Realtime concept for the full
wire format.
Caveats
Section titled “Caveats”- The realtime channel is in-process per server instance. Behind a load balancer with sticky sessions, fan-out works. Without sticky sessions, run vaultbase in cluster mode (SO_REUSEPORT) so one worker receives every WS frame for a given connection.
- Filters are evaluated server-side per event; complex filters cost CPU on the broadcast hot path.
- Disconnects emit a synthetic
closeevent withreason: string. Don’t depend on receive order — slow consumers + retries can shuffle.