Docs

Channels and connections

How a realtime connection is opened, kept alive and re-opened; publishing and receiving; channel names; message size, rate and ordering; catching up with replay; closing codes; encrypted channels; and limits.

Updated Oct 17, 2026Open in console

The connection

  1. Ticket

    The client asks for a one-time ticket for a channel (POST /api/v1/auth/ws-ticket). Your rules decide here whether the caller may subscribe; a ticket works once and expires within seconds.

  2. Connect

    The client opens wss://<project-ref>.sovarias.in/api/v1/rt/ws/<channel>?ticket=….

  3. Stay alive

    The connection is kept alive with a heartbeat every 30 seconds; a connection silent for 90 seconds is treated as gone.

  4. Re-open

    If it drops, the SDK reconnects with backoff (at most 15 seconds between tries, configurable) and a fresh ticket each time.

const room = sovaria.realtime.channel('room-42', {
  onMessage: (payload) => addMessage(payload),
  onStatus: (status) => setStatus(status),   // 'connecting' | 'live' | 'reconnecting' | 'closed'
  onError: (err) => console.warn(err),       // it keeps retrying
  maxBackoffMs: 15000,
})

await room.send({ text: 'Hello!', at: Date.now() })
room.close()

Publish and receive

  • room.send(payload) or sovaria.realtime.publish(channel, payload) sends through the API (POST /api/v1/rt/stream/publish/<channel>); your rules must allow PUBLISH for the caller.
  • Servers and functions can publish with the service role key — for example to notify users when a job finishes.
  • Every subscriber of the channel, including the sender, receives the message as { payload, … }.

Channel names

PatternUse
room-42, ordersShared channels; allow them by name in rules.
user:<user id>, user:<user id>:notificationsA user's private channels; one rule covers them all with ctx.realtime.in_own_channel == True.
db.table.<table>Database change events (Database change events).

Ordering and delivery

  • Messages on one channel arrive in the order they were published.
  • A message reaches the clients connected at that moment. Each message carries stream_seq, its number in the channel. A client that was offline catches up with replay: sovaria.realtime.replay(channel, after, limit) returns the messages after the last stream_seq it saw (up to 1,000 per call; the most recent 1,000 per channel are kept).
  • A client that can't keep up (its socket doesn't accept data within about a second) is disconnected so it doesn't slow the channel down; it reconnects and replays.
let lastSeen = 0
const ch = sovaria.realtime.channel('orders', {
  onMessage: (payload, raw) => { lastSeen = raw.stream_seq ?? lastSeen; show(payload) },
  onStatus: async (s) => {
    if (s === 'live' && lastSeen) {
      const missed = await sovaria.realtime.replay('orders', lastSeen, 200)
      missed.events?.forEach((e) => show(e.payload))
    }
  },
})

Why a connection closes

CodeMeansDo
4401Not authorized: bad, expired or reused ticket, or the user signed out.Get a new ticket (the SDK does); if it keeps failing, check the channel rules.
4408Policy violation: a rule or limit refused the connection or a message.Check rules and limits (message size, events per second).
1013Slow consumer: the client didn't read fast enough.Reconnect and replay; handle messages faster.

End-to-end encrypted channels

On paid plans a channel can be end-to-end encrypted: clients fetch the channel's key wrapped for their own public key, encrypt messages before sending and decrypt after receiving, so Sovaria relays them without being able to read them. Keys can be rotated and revoked (REST: realtime and end-to-end encryption).

FreeProUltraTeamEnterprise
End-to-end encrypted realtime—✓✓✓✓

Limits

Per project you can lower these further and cap events per second per connection under Realtime › Settings (Realtime settings and limits).

FreeProUltraTeamEnterprise
Concurrent realtime connections1005001,5005,00020,000
Realtime channels205005,00020,000100,000
Realtime connections per signed-in user2050100200500
Largest realtime message0 MB0 MB0 MB0 MB0 MB
Monthly realtime messages2,000,0005,000,00015,000,00075,000,000300,000,000
Recent realtime messages kept per channel for replay1,0001,0001,0001,0001,000
Something unclear or missing on this page?Tell us