52.9. Logical Replication Message Formats

This section describes the detailed format of each logical replication message. These messages are returned either by the replication slot SQL interface or are sent by a walsender. In case of a walsender they are encapsulated inside the replication protocol WAL messages as described in Section 52.4 and generally obey same message flow as physical replication.

  • Begin

      • Byte1('B')

      • Identifies the message as a begin message.

    • Int64

      • The final LSN of the transaction.
    • Int64

      • Commit timestamp of the transaction. The value is in number of microseconds since PostgreSQL epoch (2000-01-01).
    • Int32

      • Xid of the transaction.
  • Commit

      • Byte1('C')

      • Identifies the message as a commit message.

    • Int8

      • Flags; currently unused (must be 0).
    • Int64

      • The LSN of the commit.
    • Int64

      • The end LSN of the transaction.
    • Int64

      • Commit timestamp of the transaction. The value is in number of microseconds since PostgreSQL epoch (2000-01-01).
  • Origin

      • Byte1('O')

      • Identifies the message as an origin message.

    • Int64

      • The LSN of the commit on the origin server.
    • String

      • Name of the origin.

Note that there can be multiple Origin messages inside a single transaction.

  • Relation

      • Byte1('R')

      • Identifies the message as a relation message.

    • Int32

      • ID of the relation.
    • String

      • Namespace (empty string for pg_catalog ).
    • String

      • Relation name.
    • Int8

      • Replica identity setting for the relation (same as relreplident in pg_class ).
    • Int16

      • Number of columns.

Next, the following message part appears for each column:

  • Int8

    • Flags for the column. Currently can be either 0 for no flags or 1 which marks the column as part of the key.

    • String

      • Name of the column.
    • Int32

      • ID of the column's data type.
    • Int32

      • Type modifier of the column ( atttypmod ).
  • Type

      • Byte1('Y')

      • Identifies the message as a type message.

    • Int32

      • ID of the data type.
    • String

      • Namespace (empty string for pg_catalog ).
    • String

      • Name of the data type.
  • Insert

      • Byte1('I')

      • Identifies the message as an insert message.

    • Int32

      • ID of the relation corresponding to the ID in the relation message.
    • Byte1('N')

      • Identifies the following TupleData message as a new tuple.
    • TupleData

      • TupleData message part representing the contents of new tuple.
  • Update

      • Byte1('U')

      • Identifies the message as an update message.

    • Int32

      • ID of the relation corresponding to the ID in the relation message.
    • Byte1('K')

      • Identifies the following TupleData submessage as a key. This field is optional and is only present if the update changed data in any of the column(s) that are part of the REPLICA IDENTITY index.
    • Byte1('O')

      • Identifies the following TupleData submessage as an old tuple. This field is optional and is only present if table in which the update happened has REPLICA IDENTITY set to FULL.
    • TupleData

      • TupleData message part representing the contents of the old tuple or primary key. Only present if the previous 'O' or 'K' part is present.
    • Byte1('N')

      • Identifies the following TupleData message as a new tuple.
    • TupleData

      • TupleData message part representing the contents of a new tuple.

The Update message may contain either a 'K' message part or an 'O' message part or neither of them, but never both of them.

  • Delete

      • Byte1('D')

      • Identifies the message as a delete message.

    • Int32

      • ID of the relation corresponding to the ID in the relation message.
    • Byte1('K')

      • Identifies the following TupleData submessage as a key. This field is present if the table in which the delete has happened uses an index as REPLICA IDENTITY.
    • Byte1('O')

      • Identifies the following TupleData message as a old tuple. This field is present if the table in which the delete has happened has REPLICA IDENTITY set to FULL.
    • TupleData

      • TupleData message part representing the contents of the old tuple or primary key, depending on the previous field.

The Delete message may contain either a 'K' message part or an 'O' message part, but never both of them.

The following message parts are shared by the above messages.

  • TupleData

      • Int16

      • Number of columns.

Next, one of the following submessages appears for each column:

  • Byte1('n')

    • Identifies the data as NULL value.

Or

  • Byte1('u')

    • Identifies unchanged TOASTed value (the actual value is not sent).

Or

  • Byte1('t')

    • Identifies the data as text formatted value.

    • Int32

      • Length of the column value.
    • Byte n

      • The value of the column, in text format. (A future release might support additional formats.) n is the above length.