When building Agentic AI systems, memory consistency is everything.
Your agents may reason, plan, and interact autonomously—but if they can’t reliably recall and share knowledge across distributed nodes, their intelligence collapses. That’s why replicated vector databases are the foundation of scalable cognition.
In this post, we’ll show how to set up a PostgreSQL Master–Replica cluster with pgvector using Docker Compose—creating a fault-tolerant, self-replicating AI memory system ready for real-world agent workloads.
Imagine a swarm of AI agents constantly generating and embedding new knowledge: customer interactions, support transcripts, RAG-indexed documents, embeddings for semantic memory.
Each agent must:
That’s where this pgvector master–replica pattern shines:
This pattern is the seed of enterprise-grade Agentic AI infrastructure, ensuring memory reliability, scalability, and fault tolerance.
pgvector-repl/
├─ docker-compose.yml
├─ primary/
│ └─ init/
│ └─ 01_init.sql
├─ replica/
│ └─ bootstrap.sh
└─ demo.pyversion: "3.9"
services:
primary:
image: pgvector/pgvector:pg16
container_name: pg_primary
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: vectordb
ports:
- "5432:5432"
volumes:
- primary-data:/var/lib/postgresql/data
- ./primary/init:/docker-entrypoint-initdb.d
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres -d vectordb"]
interval: 3s
timeout: 3s
retries: 30
replica:
image: pgvector/pgvector:pg16
container_name: pg_replica
depends_on:
primary:
condition: service_healthy
environment:
POSTGRES_PASSWORD: postgres
ports:
- "5433:5432"
volumes:
- replica-data:/var/lib/postgresql/data
- ./replica/bootstrap.sh:/usr/local/bin/bootstrap.sh
entrypoint: ["/bin/bash", "-c", "/usr/local/bin/bootstrap.sh"]
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres -d vectordb -h localhost -p 5432"]
interval: 3s
timeout: 3s
retries: 30
volumes:
primary-data:
replica-data:-- Postgres 16 + pgvector + streaming replication
-- 1) Replication settings
ALTER SYSTEM SET wal_level = 'replica';
ALTER SYSTEM SET max_wal_senders = 10;
ALTER SYSTEM SET max_replication_slots = 10;
ALTER SYSTEM SET wal_keep_size = '256MB';
-- 2) Replication user
DO $$
BEGIN
IF NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'replicator') THEN
CREATE ROLE replicator WITH REPLICATION LOGIN PASSWORD 'replpass';
END IF;
END$$;
-- 3) Enable adminpack to modify pg_hba.conf
CREATE EXTENSION IF NOT EXISTS adminpack;
-- 4) Allow replication from Docker subnet
SELECT pg_file_write(
'pg_hba.conf',
E'\n# --- Allow replication from Docker bridge network ---\n' ||
E'host replication replicator 172.18.0.0/16 md5\n' ||
E'host all all 0.0.0.0/0 md5\n',
TRUE
);
-- 5) Enable pgvector and create demo table
CREATE EXTENSION IF NOT EXISTS vector;
DROP TABLE IF EXISTS items;
CREATE TABLE items (
id serial PRIMARY KEY,
embedding vector(3),
note text
);
-- 6) Reload config and create replication slot
SELECT pg_reload_conf();
DO $$
BEGIN
IF NOT EXISTS (SELECT 1 FROM pg_replication_slots WHERE slot_name='replica1') THEN
PERFORM pg_create_physical_replication_slot('replica1');
END IF;
END$$;#!/usr/bin/env bash
set -euo pipefail
PRIMARY_HOST="primary"
PRIMARY_PORT="5432"
REPL_USER="replicator"
REPL_PASS="replpass"
DATA_DIR="/var/lib/postgresql/data"
echo "Waiting for primary to be ready..."
until pg_isready -h "$PRIMARY_HOST" -p "$PRIMARY_PORT" -U postgres >/dev/null 2>&1; do
sleep 1
done
if [ -s "$DATA_DIR/PG_VERSION" ]; then
echo "Replica already initialized."
exec docker-entrypoint.sh postgres
fi
echo "Cloning base backup..."
export PGPASSWORD="$REPL_PASS"
rm -rf "$DATA_DIR"
gosu postgres pg_basebackup \
-h "$PRIMARY_HOST" -p "$PRIMARY_PORT" \
-U "$REPL_USER" -D "$DATA_DIR" -Fp -Xs -P -R
cat >> "$DATA_DIR/postgresql.auto.conf" <<EOF
primary_conninfo = 'host=$PRIMARY_HOST port=$PRIMARY_PORT user=$REPL_USER password=$REPL_PASS application_name=replica1'
primary_slot_name = 'replica1'
EOF
exec docker-entrypoint.sh postgresMake it executable:
chmod +x replica/bootstrap.shimport time
import psycopg2
PRIMARY_DSN = "host=localhost port=5432 dbname=vectordb user=postgres password=postgres"
REPLICA_DSN = "host=localhost port=5433 dbname=vectordb user=postgres password=postgres"
emb = [0.12, 0.34, 0.56]
note = "Inserted on primary; watch it appear on replica."
with psycopg2.connect(PRIMARY_DSN) as conn:
conn.autocommit = True
with conn.cursor() as cur:
cur.execute("CREATE EXTENSION IF NOT EXISTS vector;")
cur.execute("INSERT INTO items (embedding, note) VALUES (%s, %s) RETURNING id;", (emb, note))
row_id = cur.fetchone()[0]
print(f"Inserted id={row_id} into primary.")
deadline = time.time() + 20
while time.time() < deadline:
with psycopg2.connect(REPLICA_DSN) as conn:
with conn.cursor() as cur:
cur.execute("SELECT id, embedding::text, note FROM items WHERE id = %s;", (row_id,))
r = cur.fetchone()
if r:
print("Replica has it:", r)
break
time.sleep(1)Run:
pip install psycopg2-binary
docker compose up -d
python demo.pyExpected output:
Inserted id=1 into primary.
Replica has it: (1, '[0.12,0.34,0.56]', 'Inserted on primary; watch it appear on replica.')On replica:
docker exec -it pg_replica psql -U postgres -d vectordb \
-c "SELECT status, sent_lsn, write_lsn, flush_lsn, replay_lsn FROM pg_stat_wal_receiver;"âś… Status should be streaming.
| Goal | Next Step |
|---|---|
| Scale reads | Add more replicas |
| Automatic failover | Use Patroni or repmgr |
| Multi-agent RAG apps | Integrate with LanceDB, Milvus, or LangChain |
| Vector search speed | Add HNSW or IVF indexes |
| Secure comms | Use SSL and scram-sha-256 passwords |
This tiny setup demonstrates something profound: a self-healing, streaming-replicated vector memory that forms the backbone of scalable, fault-tolerant Agentic AI systems.
When your AI agents have an unbreakable memory fabric, they can truly think—together.