drift Docs
Start
What is Drift?
The tour, if you are new here.
Why Drift?
The case for a smaller cloud.
Getting started
Nothing to deployed, in one command.
Architecture
How a slice is put together.
What it costs
The free grant, five unit prices, two rules.
Build
Canvas
Static sites, same origin as your API.
Tools
Operate
Auth
Accounts, tokens and scopes.
Security
Boundaries, sandboxing and hardening.

Backbone Realtime

In-slice pub/sub over WebSocket. Browser clients open a socket to a named channel; anything one client sends is fanned out to every other client on that channel, live. There's no broker to run and no second service. The channel lives in the slice, same-origin with your Canvas site, so there's no cross-origin handshake.

A channel has no authentication and no authorization.

The upgrade checks three things: the channel name's charset, the DRIFT_ALLOWED_ORIGINS allowlist (an empty allowlist permits every origin), and the slice's connection cap. Anyone who can reach the Canvas listener and knows or guesses a channel name can subscribe to it and broadcast to everyone on it. Put nothing on a channel you would not hand to an anonymous caller, and keep the privileged half behind a function.
Node.js
// in your Canvas site's JavaScript: join a channel and react to others
const ws = new WebSocket(`wss://${location.host}/realtime/board:42`);
ws.onmessage = (e) => applyDelta(JSON.parse(e.data));
// broadcast your own change to everyone else on the channel
ws.send(JSON.stringify({ type: "move", x: 10, y: 20 }));

A function can also publish to a channel server-side, fanning an event out to every subscriber, or check how many are connected:

Go
// fan a message out to everyone on the channel; returns the recipient count
n, _ := drift.Backbone.Realtime.Channel("board:42").Publish(map[string]any{"type": "reset"})
live, _ := drift.Backbone.Realtime.Channel("board:42").Presence()

This is what drives live cursors and collaborative editing in the Myral whiteboard demo: clients exchange cursor and element deltas over the channel, and a normal function persists the result for durability and late-joiner catch-up.

Realtime limits

LimitBehaviour past it
Channel name: alphanumerics and : . _ ~ -, 1–256 bytesThe upgrade answers 400.
512 KiB per messageThe frame is dropped silently, and no error reaches the sender.
128 connections per channelThe socket is closed with code 1013, "channel full".
2,048 live channels per sliceClosed the same way.
Concurrent connections across the slice, from backbone.realtime_connectionsThe upgrade answers 503. A slice with no positive value caps at 50.

Realtime is a shared channel between many clients.

To stream a response from a single function call instead, add stream=sse or stream=ws to the function; see Atomic streaming.