Skip to content
Appwrite Realtime

Everything in Appwrite is realtime_

Rows, files, function executions, sessions, teams, and presence all emit events on the same WebSocket. Subscribe once, get changes in milliseconds instead of polling, and only ever receive what the user can read.

Appwrite events

  • Databasesrows
  • Storagefiles
  • Functionsexecutions
  • Authaccount
  • Presencepresences

Realtime

1 WebSocket
Web app
Mobile app
Dashboard
Not just databases
Every service
Shared by all subscriptions
1 socket
From write to subscriber
Milliseconds
Filtered server-side
Queries
Live online status
Presence

One connection, many subscriptions

Create a Realtime client once and every subscription shares a single WebSocket. Add one with subscribe(), swap its channels or queries with update(), and drop it with unsubscribe(), all without reconnecting.

rowsfilespresences

Realtime client

1 WebSocket

Every service publishes to a channel

Databases, Storage, Functions, Auth, teams, and presence all stream on the same socket. The Channel helper builds the string with a fluent API, so leave an ID blank for a wildcard or append .create() to narrow the stream.

Databases

  • Channel.tablesdb('main').table('orders').row()

    tablesdb.<ID>.tables.<ID>.rows

  • Channel.tablesdb('main').table('orders').row('8f2a')

    tablesdb.<ID>.tables.<ID>.rows.<ID>

  • Channel.rows()

    rows

Storage

  • Channel.bucket('media').file()

    buckets.<ID>.files

  • Channel.bucket('media').file('invoice')

    buckets.<ID>.files.<ID>

  • Channel.files()

    files

Functions

  • Channel.executions()

    executions

  • Channel.function('checkout')

    functions.<ID>

  • Channel.executions().create()

    executions.create

Auth, teams, and presence

  • Channel.account()

    account

  • Channel.teams()

    teams.*

  • Channel.presences()

    presences

Filter events before they reach you

Pass queries when you subscribe and Appwrite filters events on the server, so your callback only runs for updates that match. The methods are the ones you already use for lists, from equal to isNull and or.

Events on the channel

  • person: 'paige'match
  • person: 'walter'dropped
  • person: 'paige'match

Filtered on the server

[Query.equal('person', ['paige'])]

Presence that is durable and live

A presence record carries a user, a free-form status, optional metadata, and an expiry. List presences to see who is here, and subscribe for upsert, update, and delete events in milliseconds.

Who is here

presences
  • PApaige@example.comediting
  • WAwalter@example.comonline
  • HAhappy@example.comaway

expiresAt

Slides on heartbeat

A predictable payload on every event

Every message carries the events that triggered it, the channels that can receive it, a server timestamp, and a payload matching the resource response model. Branch on the event names, then apply the payload.

Every message carries

eventsstring[]

['tablesdb.main.tables.orders.rows.8f2a.update']

channelsstring[]

['rows', 'tablesdb.main.tables.orders.rows']

payloadobject

{ $id: '8f2a', status: 'paid' }

Permission-aware subscriptions

Subscriptions use the same permissions as the rest of Appwrite, so a user only receives updates for resources they can read. Realtime uses the session you had when you subscribed, so reconnect when it changes.

Row updated

Permission.read(Role.team('acme'))

paige@example.com
Event delivered
toby@example.com
Nothing delivered

Tools built for developers and agents_

API-first by design. Use the Console, Realtime, SDKs, CLI, Terraform, MCP, and agent skills on the same project.

FAQ_

Realtime is a third protocol for talking to Appwrite, alongside REST and GraphQL. Instead of requesting new data over HTTP, you subscribe once and the server pushes new data to every connected client over a WebSocket as soon as it changes. Subscriptions cover events from all of Appwrite services, not just databases.

Start building with Realtime_

Subscribe to your first channel and watch rows, files, executions, and presence updates arrive as they happen.