PostgreSQL + pgvector

If your team already runs PostgreSQL, Recall can keep its memory there, with the pgvector extension. Every Recall capability works on it: typed facts, corrections, history, keyword search, cached reads, and agent resume, with each agent write checked against its lease inside the write's own transaction.

Before you start

Run the memory server on PostgreSQL

  1. Start PostgreSQL with pgvector, if it is not running yet:

    docker run -d -e POSTGRES_PASSWORD=recall -p 5432:5432 pgvector/pgvector:pg17
  2. Add Recall to Claude Code as an MCP server:

    claude mcp add recall \
      -e RECALL_BACKEND=pgvector \
      -e DATABASE_URL=postgres://postgres:recall@localhost:5432/postgres \
      -- recall mcp -write

    Put the password in PGPASSWORD instead of the URL if you prefer. Add -agent for the agent resume tools. Other MCP hosts take the same command and variables, or the flags recall -backend pgvector -url postgres://... mcp -write.

  3. Restart Claude Code and ask it to remember something. The first write creates the recall schema and the collection's table.

recall setup and the Recall plugin set up a polign_db connection. With PostgreSQL, add the MCP server yourself as in step 2.

Use it from Go

import (
	"github.com/Polign/recall"
	"github.com/Polign/recall/backend/pgvector"
)

backend, err := pgvector.New(pgvector.Config{
	URL: os.Getenv("DATABASE_URL"),
})
defer backend.Close()
client, err := recall.NewClient(recall.Config{
	Backend:    backend,
	Collection: "team_memory",
	Registry:   recall.DefaultRegistry(),
	Embedder:   recall.LexicalEmbedder{},
})

pgvector.Config also takes a Schema (default recall), the TextSearchConfig for keyword search (default english), and a Pool to share a pgx connection pool you already have. The package uses pgx, which a program pulls in only by importing it.

What gets stored

RecallPostgreSQL
A collectionA table in the recall schema, named after the collection, created on the first write with the first vector's size
An eventA row: the event ID, the vector, and the metadata as jsonb
IndexesHNSW on the vector (cosine), GIN on the metadata, a generated tsvector for keyword search, and an index on observation time
Bookkeepingrecall_collections maps each collection to its table and counts its writes, which is what cached reads check; recall_leases holds agent leases

Agent resume and fenced writes

Leases are rows in recall_leases, taken and renewed by the database's own clock, so recall mcp -agent and Client.Resume work as they do on polign_db. Each agent write reads its lease row with FOR SHARE in the same transaction as the write. A process that stalled past its lease is refused even when its own clock still says the lease is fresh, and a takeover waits for an in-flight write to commit. See Resume for how actions and leases fit together.

Good to know

If something goes wrong

What you seeWhat to do
unknown backend "pgvector"Your recall is older than 0.19.0. Upgrade it.
the vector extension is not installed and could not be createdInstall pgvector on the server, then run CREATE EXTENSION vector as a role that may.
holds 256-dimensional vectors, not 384The collection was created with another embedder. Use a new -collection when you change embedders.
lease_held on resumeAnother process holds the agent, or one died less than a lease time ago. Wait for the lease to expire.

Source & license

The PostgreSQL backend is part of Recall, open source under the Apache License 2.0, in github.com/Polign/recall. Bug reports and pull requests go there.