Shipping a Postgres vector store is the easy part — keeping it fast and accurate in production is the job. This day covers the operational instruments: readingpg_stat_statementsto find the queries that actually hurt, taming index bloat and autovacuum on high-churn embedding tables, knowing exactly when to REINDEX CONCURRENTLY, and detecting retrieval-quality drift before your users do.
A Postgres + pgvector store that worked perfectly on launch day will degrade silently. Not because the code changed — because the data changed underneath it. Embedding tables are unusually hostile to Postgres's storage model, and the failure mode is rarely a crash. It's a query that used to take 8 ms now taking 400 ms, or a top-5 retrieval that used to be right now quietly returning the wrong chunks.
Operating a vector store means watching three independent things, and confusing them costs you incidents:
A normal OLTP table has only the first two. The third — retrieval quality — is what makes a vector store special and is the theme that runs through this whole day.
Three properties make embedding tables uniquely demanding:
For the rest of this day, the toolbox is:
pg_stat_statements — normalized, aggregated query stats. Your #1 tool for "what is slow."pg_stat_user_tables / pg_stat_user_indexes — dead tuples, last (auto)vacuum, scan counts, index usage.pgstattuple (extension) — exact bloat measurement when you need ground truth.If you only remember one framing: traditional monitoring tells you the query is slow; only an eval set tells you the answer is wrong. You need both.