replicationStats

Return every WAL sender on this server (pg_stat_replication) with its state, sync_state, sent/write/flush/replay LSNs, the byte gap to replay (on a cascading standby, measured from the WAL it has received), and write_lag/flush_lag/replay_lag as SECONDS -- plus replication…

read-onlyany connectionsweeps replication groupsweeps group

Synopsis

replicationStats()

Description

Return every WAL sender on this server (pg_stat_replication) with its state, sync_state, sent/write/flush/replay LSNs, the byte gap to replay (on a cascading standby, measured from the WAL it has received), and write_lag/flush_lag/replay_lag as SECONDS -- plus replication origin progress. Senders are keyed by application_name plus pid, because a walreceiver's default application_name is its cluster_name and Debian sets that per major rather than per host, so two standbys routinely share one; a name-only key would fold them into a single entry.

This is the only source of replication lag as a TIME: replicationSlots reports what a slot RETAINS in bytes, and subscriptionStats cannot measure lag at all because neither of its LSN columns references the publisher. Serves physical standbys and logical subscribers alike. Two readings that are routinely misread: the view is security-restricted PER ROW rather than refused, so a role without pg_read_all_stats sees the senders exist with many columns null, which looks like an idle replica rather than a permission answer; and the lag columns revert to NULL a short time after a standby has entirely caught up and WAL activity stops, so a null lag on an idle replica means caught up while a non-null one is the last measurement rather than the current state.

Parameters

None of its own.

Also accepts connection, replication_group, group, role, described once under arguments every tool takes.

Output

WAL senders and replication origins. An absent extension or a missing grant is reported as {error, hint} instead.

FieldType
notestring | null
originsobject | null
replicationobject | null

Scope

This reading is instance-wide -- every database on the same postmaster returns it identically, so asking each of them in turn repeats one answer. The counters here are each server's own, so members of a replication group legitimately disagree and the answer is their sum, not the primary's copy.

Example mocked data

Request

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "replicationStats",
    "arguments": {
      "connection": "shop_prod"
    }
  }
}

Result

{
  "replication": {
    "shop-replica-1 (pid 48211)": {
      "pid": 48211,
      "user": "replicator",
      "application_name": "shop-replica-1",
      "client_addr": "10.0.2.21",
      "state": "streaming",
      "sync_state": "async",
      "sent_lsn": "3A/1C0024F8",
      "write_lsn": "3A/1C0024F8",
      "flush_lsn": "3A/1C0024F8",
      "replay_lsn": "3A/1BFF1E20",
      "write_lag_s": 0.002,
      "flush_lag_s": 0.003,
      "replay_lag_s": 0.041,
      "replay_behind_bytes": 67160
    }
  },
  "origins": {
    "error": "could not read pg_replication_origin_status",
    "hint": "reading replication origin progress needs the superuser or a role granted SELECT on pg_replication_origin_status."
  },
  "note": "pg_stat_replication is security-restricted per row rather than refused."
}

Invented values on a fictional shop database, shaped by and checked against this tool's output schema. Real output is returned as structuredContent to clients that negotiate MCP 2025-06-18 or later.

See also

listForeignTables, listForeignServers, listPublications, listSubscriptions, subscriptionStats, replicationSlots