Documentationpgraft Documentation

pgraft SQL Functions

Cluster Bootstrap

Initialize pgraft metadata, set cluster identity, and register members. Execute these commands on the elected leader once PostgreSQL configuration matches across nodes.

pgraft_init()

Bootstraps the cluster catalog and Raft log. Automatically executed during CREATE EXTENSION pgraft but exposed for automation.

Initialize cluster

-- Run after CREATE EXTENSION if manual bootstrap is required
SELECT pgraft_init();

pgraft_add_node()

Adds a follower node to the membership roster. The follower must be online with matching pgraft.cluster_id and a unique pgraft.node_id.

Register followers

SELECT pgraft_add_node(2, '10.0.0.12', 7002);
SELECT pgraft_add_node(3, '10.0.0.13', 7003);

SELECT node_id,
       state,
       match_index,
       commit_index
  FROM pgraft_get_nodes();

pgraft_remove_node()

Removes a node from voting membership. Use before decommissioning hardware or performing destructive maintenance.

Drain a node

SELECT pgraft_remove_node(3);
SELECT pgraft_quorum_met() AS quorum_ok;

Leadership Control

Determine leadership, orchestrate manual failovers, and coordinate rolling maintenance with declarative SQL calls.

pgraft_get_leader()

Returns the node ID of the current leader according to the calling session.

Who is leader?

SELECT pgraft_get_leader();

pgraft_is_leader()

Boolean helper for routing logic and connection pools.

Am I leader?

SELECT pgraft_is_leader();

pgraft_transfer_leadership()

Requests that the current leader hand off leadership to another node to support planned maintenance or topology changes.

Promote another node

SELECT pgraft_transfer_leadership(2);
SELECT pgraft_get_leader();

Operational Monitoring

These read-only views expose Raft health, replication status, and worker uptime. Use them to drive dashboards and alerting.

Cluster status

SELECT node_id,
       leader_id,
       current_term,
       state,
       num_nodes,
       messages_processed,
       elections_triggered
  FROM pgraft_get_cluster_status();

Replication lag

SELECT node_id,
       match_index,
       commit_index,
       lag_entries,
       state
  FROM pgraft_log_get_replication_status()
 ORDER BY lag_entries DESC;

Node connectivity

SELECT node_id,
       address,
       port,
       last_heartbeat_ms,
       replication_lag_bytes
  FROM pgraft_get_nodes();

Log volume

SELECT first_index,
       last_index,
       total_entries,
       disk_usage_mb
  FROM pgraft_log_get_stats();

Runtime Configuration

Update pgraft configuration dynamically and persist durable overrides without restarting PostgreSQL.

pgraft_set_config()

Adjusts any pgraft GUC at runtime on all nodes.

Tune consensus timing

SELECT pgraft_set_config('heartbeat_interval', '75ms');
SELECT pgraft_set_config('election_timeout', '900ms');

pgraft_save_config()

Persists in-memory overrides to catalog tables so they survive a restart.

Persist changes

SELECT pgraft_save_config();

pgraft_get_config()

Shows active configuration values, including defaults and overrides.

Inspect configuration

SELECT * FROM pgraft_get_config();

Replicated KV Store

pgraft ships with a lightweight key-value store for coordination objects. Reads and writes follow the same consensus guarantees as SQL transactions.

pgraft_kv_put()

Store metadata

SELECT pgraft_kv_put('configs/maintenance', jsonb_build_object('window', '02:00 UTC', 'duration', '30m'));

pgraft_kv_get()

Read value

SELECT pgraft_kv_get('configs/maintenance');

pgraft_kv_delete()

Delete key

SELECT pgraft_kv_delete('configs/maintenance');

Health probe

DO $$
DECLARE
  k TEXT := 'health_' || extract(epoch FROM now());
  v TEXT := md5(random()::text);
  r TEXT;
BEGIN
  PERFORM pgraft_kv_put(k, to_jsonb(v));
  SELECT pgraft_kv_get(k)::text INTO r;
  IF r IS NULL OR r <> to_jsonb(v)::text THEN
    RAISE EXCEPTION 'KV health check failed';
  END IF;
  PERFORM pgraft_kv_delete(k);
END;
$$;

Troubleshooting Toolkit

Use these recipes to detect unhealthy patterns, salvage lagging followers, and debug Raft behavior in production.

Detect unhealthy elections

SELECT node_id,
       elections_triggered,
       current_term,
       elections_triggered::float / GREATEST(current_term, 1) AS elections_per_term
  FROM pgraft_get_cluster_status()
 WHERE elections_triggered::float / GREATEST(current_term, 1) > 2.0;

Find stalled followers

SELECT node_id,
       lag_entries,
       state
  FROM pgraft_log_get_replication_status()
 WHERE lag_entries > 1000
    OR state = 'stalled';

Reset follower

-- Execute on lagging follower after maintenance
SELECT pgraft_log_sync_with_leader();

Expose debug info

SELECT pgraft_set_debug(true);
-- Reproduce issue
SELECT pgraft_set_debug(false);

Collect diagnostics

#!/usr/bin/env bash
psql -f - <<'SQL'
o /tmp/pgraft-diagnostics.txt
SELECT now() AS collected_at;
SELECT * FROM pgraft_get_cluster_status();
SELECT * FROM pgraft_get_nodes();
SELECT * FROM pgraft_log_get_replication_status();
SELECT * FROM pgraft_log_get_stats();
SQL

sudo tail -200 /var/log/postgresql/postgresql-17-main.log | grep pgraft >> /tmp/pgraft-diagnostics.txt

Automation Workflows

Combine pgraft SQL with shell automation to orchestrate incident response and rolling deployments.

Rolling restart playbook

-- Assume node 1 is leader and node 2 requires maintenance
BEGIN;
  PERFORM pgraft_transfer_leadership(3);
  PERFORM pgraft_set_config('failover_enabled', 'false');
COMMIT;

-- Perform OS updates on node 2, then rejoin cluster
SELECT pgraft_set_config('failover_enabled', 'true');
SELECT * FROM pgraft_get_cluster_status();

Automated health check

#!/usr/bin/env bash
RESULT=$(psql -t -c "SELECT * FROM pgraft_health_check() WHERE severity IN ('warning', 'critical');")
if [[ -n "$RESULT" ]]; then
  echo "$(date --iso-8601=seconds) - ALERT: $RESULT" >> /var/log/pgraft-health.log
fi