Skip to main content
ctrlrun.postgres.PostgresStateStore — class, defined at src/ctrlrun/postgres.py:218
Approvals, effects and evidence in a Postgres schema (SPEC-v0.6 §4). One connection per thread, as SQLiteStateStore does: psycopg connections are not thread-safe, and the thread-local shape is the one close() is already specified against (§2.7). A connection outlives the thread that opened it, and that is a real limit worth stating. A host running agents on a bounded, recycled thread pool is fine — the same threads keep reusing the same connections. A host that starts a fresh thread per unit of work accumulates one connection per thread that ever touched the store, and Postgres connections are far scarcer than SQLite file handles: max_connections defaults to 100. close() releases every one, so the mitigation is to close a store you are done with. The conformance suite met this for real — ninety-six connections across twelve rounds of eight threads — and the failure surfaced in a case that had nothing to do with it. No pool ships. An operator may put pgbouncer in front in transaction mode, and it works because this store holds nothing session-scoped: no advisory lock, no temp table, no prepared statement it depends on surviving, no SET. That is the second reason §4.2.1 rejected advisory locks, and it is a property worth keeping deliberately rather than by luck.

Next