Deployment
Provisioning Postgres, the schema, and the worker in production.
pgmem is a library plus a SQL layer — there's no separate service to run. Deploying
it means: a Postgres with pgvector, the schema applied, your agent app importing
the SDK, and background projection workers where you use derived memory views.
Prerequisites
- A production PostgreSQL with the
pgvectorextension available. - Your agent app, with the pgmem SDK as a dependency.
Steps
Provision Postgres + pgvector
Use any managed or self-hosted Postgres with pgvector enabled. The embedding
dimension is fixed at 1536 by the schema.
Apply the schema
Apply the schema to your production database with the idempotent SQL installer (safe to re-run on every deploy):
psql "$DATABASE_URL" -v ON_ERROR_STOP=1 -f sql/migrations/install.sqlSelf-hosted Postgres can instead install pgmem as a first-class extension
(CREATE EXTENSION pgmem) from the packaged sql/extension/pgmem--*.sql. Either
way, gate releases on the schema being current — see
Versioning & migrations.
Connect the app and size the pool
Construct one PgMem per process at startup and reuse it. Size the pool for your
concurrency — max_size >= 2 is required for add_episode_bulk,
compact_async, and concurrent application/worker activity. Size it ≥ the number
of groups you ingest concurrently.
from pgmem import PgMem, PgMemConfig, PoolConfig
mem = await PgMem.create(
dsn, embedder=embedder, llm=llm,
config=PgMemConfig(pool=PoolConfig(max_size=20)),
)Run projection maintenance workers
Claim vector and graph projections refresh off the turn. Run the promotion worker as a long-lived task — in the same process or a dedicated one. Multiple workers are safe. If claims use retention deadlines, run the retention worker from the same scheduler.
from pgmem import ClaimRetentionWorker, PromotionWorker
promotion = PromotionWorker(mem)
await promotion.recover() # requeue leases from a previous crash
asyncio.create_task(promotion.run()) # poll + process in the background
asyncio.create_task(ClaimRetentionWorker(mem).serve(poll_interval=60))Notes
- Agent workers are stateless. All durable state lives in Postgres, so you can
scale workers horizontally and restart them freely;
session.resumerecovers an interrupted session. See LiveKit / voice agents. - Providers are injected, not configured — keep API keys in your secret manager
and pass the embedder/LLM into
PgMem;PgMemConfigstays pure, loggable data.
Related
- Versioning & migrations — the schema contract
- Run the promotion worker — the background loop
- Configuration — pool and other knobs
- Latency & voice safety — production latency rules