DOCUMENTATION

Realtime

Live features for your app: send messages to everyone on a channel, show who's online, and get row changes from your database as they happen.

← All docs

How it works

  • Your app opens one WebSocket connection with espobase.realtime, using the project's publishable key. A signed-in user's access token is sent automatically, never in the URL.
  • A channel is a name your app picks, like room-1. Everyone who joins the same channel in your project shares its broadcasts and presence.
  • Database changes come from the tables you turn on. Each change is re-read through your REST API as each subscriber, so the table's security rules decide who receives which row.

1. Turn realtime on for a table

In the dashboard, open Realtime (left menu) and switch the table on. The table needs a primary key. Admins and owners can change this; changes are recorded in the audit log.

2. Listen to row changes

import { createClient } from "@espobase/client";

const espobase = createClient(PROJECT_URL, PUBLISHABLE_KEY);

const room = espobase.realtime
  .channel("room-1")
  .onChange("messages", (change) => {
    // change.event: "INSERT" | "UPDATE" | "DELETE"
    // change.record: the row (INSERT, UPDATE); change.old: the primary key (DELETE)
    console.log(change.event, change.record ?? change.old);
  }, { filter: "room_id=eq.1" });

await room.join();

event is INSERT, UPDATE, DELETE or * (default). filter keeps only rows matching column=op.value (op: eq, neq, lt, lte, gt, gte). Add listeners before join().

3. Broadcast and presence

const room = espobase.realtime
  .channel("room-1", { presence: { key: user.id } })
  .onMessage("typing", (payload) => showTyping(payload))
  .onPresence((online) => showOnline(Object.keys(online)));

await room.join();
await room.track({ name: user.name });          // who's here
await room.send("typing", { name: user.name }); // everyone else on the channel

await room.leave(); // when done

Broadcasts aren't stored. Presence state is up to 2 KB per client and is removed automatically when a client disconnects.

Security

  • Row changes respect row level security: each subscriber gets only the rows its user may read, in the shape the REST API returns them.
  • Deletes send only the deleted row's primary key (the row no longer exists, so it can't be checked). Filters don't apply to deletes.
  • Broadcast and presence channels are open to anyone with your publishable key. Don't send private data by broadcast; use database changes protected by security rules instead.
  • Secret keys work only from servers (never browsers) and see every change.

Limits

  • Free: 200 simultaneous connections per project, 2M messages a month. When the monthly messages are used up, new realtime traffic is refused until the next billing cycle.
  • Pro: 500 simultaneous connections per project, 5M messages a month.
  • Group: 1,000 simultaneous connections per project, 10M messages a month.
  • Messages are what clients receive: broadcasts, presence updates and database changes. Each message is at most 64 KB; a client can send up to 50 messages per second and join up to 100 channels.