
### Persistent memory for coding agents — in the Postgres you already run
[](https://github.com/pgmnemo/pgmnemo/releases/latest)
[](LICENSE)
[](https://pypi.org/project/pgmnemo-mcp/)
[](https://pypi.org/project/pgmnemo-mcp/)
[](https://pgxn.org/dist/pgmnemo/)
[](https://github.com/pgmnemo/pgmnemo/actions/workflows/ci.yml)
[](https://www.postgresql.org/)
[](https://github.com/pgmnemo/pgmnemo/releases/tag/v0.15.0)
[](docs/img/all_metrics_history.md)
[](docs/img/all_metrics_history.md)
[Docs](docs/USAGE.md) · [Quickstart](#quickstart) · [Discussions](https://github.com/pgmnemo/pgmnemo/discussions) · [PyPI](https://pypi.org/project/pgmnemo-mcp/)
## The problem
Your coding agent finishes a debugging session. It found the root cause, fixed it, understood something about the codebase. Next session: blank slate. Same mistake, same debugging cycle, same cost.
This happens because agent memory lives in the context window. When the session ends, the memory is gone. The agent that ran 500 sessions on your codebase knows exactly as much as a fresh install.
## See it work
The following transcript was captured on a pgmnemo v0.15.1 instance holding 8,112 active lessons (July 2026). Real output, copied from the session.
**Session 1** — an agent debugs a connection-pooling issue and writes what it learned:
```sql
SELECT pgmnemo.ingest(
'developer', 99, 'connection-pooling',
'When PgBouncer runs in transaction mode, prepared statements fail
silently. Switch to session mode, or disable the statement cache
(statement_cache_mode=none in asyncpg).',
4, NULL, 'demo_readme_proof'
);
-- Result: 45087
```
One SQL call. The lesson is stored in your Postgres with a provenance link (`commit_sha`), indexed for hybrid retrieval. No LLM API call on the write path.
**Session 2** — a different agent, fresh context, hits the same problem. It asks memory:
```sql
SELECT lesson_id, score, lesson_text
FROM pgmnemo.recall_lessons(
query_embedding := NULL::vector, k := 3,
role_filter := 'developer',
query_text := 'prepared statements broken with pgbouncer'
);
[1] id=45087 score=0.0500
When PgBouncer runs in transaction mode, prepared statements fail
silently. Switch to session mode, or disable the statement cache
(statement_cache_mode=none in asyncpg).
```
The lesson from Session 1 surfaces as the top result. The second agent skips the debugging cycle entirely.
The score of `0.0500` is BM25-only (no embedding vector was passed with this lesson). With embeddings configured, hybrid vector+BM25 recall produces richer ranking — but even text-only search finds the right answer when the vocabulary overlaps. Run `EXPLAIN ANALYZE` on any recall query to see exactly what Postgres did.