Realtime

Realtime Protocol

The Realtime Protocol is a set of message formats used for communication over a WebSocket connection between a Realtime client and server. These messages are used to initiate a connection, update access tokens, receive system status updates, and receive real-time updates from the Postgres database.

Connection

In the initial message, the client sends a message specifying the features they want to use (Broadcast, Presence, Postgres Changes).


_23
{
_23
"event": "phx_join",
_23
"topic": string,
_23
"payload": {
_23
"config": {
_23
"broadcast": {
_23
"self": boolean
_23
},
_23
"presence": {
_23
"key": string
_23
},
_23
"postgres_changes": [
_23
{
_23
"event": "*" | "INSERT" | "UPDATE" | "DELETE",
_23
"schema": string,
_23
"table": string,
_23
"filter": string + '=' + "eq" | "neq" | "gt" | "gte" | "lt" | "lte" | "in" + '.' + string
_23
}
_23
]
_23
}
_23
},
_23
"ref": string
_23
}

In response, the server sends the Postgres configuration with a unique ID. With this ID, the client should route incoming changes to the appropriate callback.


_19
{
_19
"event": "phx_reply",
_19
"topic": string,
_19
"payload": {
_19
"response": {
_19
"postgres_changes": [
_19
{
_19
"id": number,
_19
"event": "*" | "INSERT" | "UPDATE" | "DELETE",
_19
"schema": string,
_19
"table": string,
_19
"filter": string + '=' + "eq" | "neq" | "gt" | "gte" | "lt" | "lte" | "in" + '.' + string
_19
}
_19
]
_19
},
_19
"status": "ok" | "error"
_19
},
_19
"ref": string
_19
}

System messages

System message are used to inform a client about the status of the Postgres subscription. The payload.status indicates if the subscription successful or not. The body of the payload.message can be "Subscribed to PostgreSQL" or "Subscribing to PostgreSQL failed" with subscription params.


_11
{
_11
"event": "system",
_11
"topic": string,
_11
"payload":{
_11
"channel": string,
_11
"extension": "postgres_changes",
_11
"message": "Subscribed to PostgreSQL" | "Subscribing to PostgreSQL failed",
_11
"status": "ok" | "error"
_11
},
_11
"ref": null,
_11
}

Heartbeat

The heartbeat message should be sent every 30 seconds to avoid a connection timeout.


_10
{
_10
"event": "heartbeat",
_10
"topic": "phoenix",
_10
"payload": {},
_10
"ref": string
_10
}

Access token

To update the access token, you need to send to the server a message specifying a new token in the payload.access_token value.


_10
{
_10
"event": "access_token",
_10
"topic": string,
_10
"payload":{
_10
"access_token": string
_10
},
_10
"ref": string
_10
}

Postgres CDC message

Realtime sends a message with the following structure. By default, the payload only includes new record changes, and the old entry includes the changed row's primary id. If you want to receive old records, you can set the replicate identity of your table to full. Check out this section of the guide.


_17
{
_17
"event": "postgres_changes",
_17
"topic": string,
_17
"payload": {
_17
"data": {
_17
schema: string,
_17
table: string,
_17
commit_timestamp: string,
_17
eventType: "*" | "INSERT" | "UPDATE" | "DELETE",
_17
new: {[key: string]: boolean | number | string | null},
_17
old: {[key: string]: number | string},
_17
errors: string | null
_17
},
_17
"ids": Array<number>
_17
},
_17
"ref": null
_17
}

Broadcast message

Structure of the broadcast event


_10
{
_10
"event": "broadcast",
_10
"topic": string,
_10
"payload": {
_10
"event": string,
_10
"payload": {[key: string]: boolean | number | string | null | undefined},
_10
"type": "broadcast"
_10
},
_10
"ref": null
_10
}

Presence message

The Presence events allow clients to monitor the online status of other clients in real-time.

State update

After joining, the server sends a presence_state message to a client with presence information. The payload field contains keys in UUID format, where each key represents a client and its value is a JSON object containing information about that client.


_10
{
_10
"event": "presence_state",
_10
"topic": string,
_10
"payload": {
_10
[key: string]: {metas: Array<{phx_ref: string, name: string, t: float}>}
_10
},
_10
"ref": null
_10
}

Diff update

After a change to the presence state, such as a client joining or leaving, the server sends a presence_diff message to update the client's view of the presence state. The payload field contains two keys, joins and leaves, which represent clients that have joined and left, respectively. The values associated with each key are UUIDs of the clients.


_10
{
_10
"event": "presence_diff",
_10
"topic": string,
_10
"payload": {
_10
"joins": {metas: Array<{phx_ref: string, name: string, t: float}>},
_10
"leaves": {metas: Array<{phx_ref: string, name: string, t: float}>}
_10
},
_10
"ref": null
_10
}