Postgres
pg_textsearch
BM25 / Keyword
pgvectorscale
Vector / Semantic
Zero Complexity
Forget provisioning three separate systems. It's just one database.
Zero Latency
Queries run where your data lives. No ETL pipelines or sync lag.
Total Consistency
Single source of truth. Writes and searches are transactionally safe.
pg_textsearch
BM25 / Keyword
Modern ranked text search as a native Postgres extension. Industry-standard BM25 scoring with the <@> operator, Block-Max WAND optimization, and parallel index builds.
CREATE INDEX ON documents USING bm25(content) WITH (text_config='english'); SELECT * FROM documents ORDER BY content <@> 'database system' LIMIT 10;Supports 29 languages
Configurable parameters
pgvectorscale
Vector / Semantic
High-performance embedding search built on top of pgvector.
The StreamingDiskANN index delivers 28x lower p95
latency and 16x higher throughput than Pinecone's storage-optimized index.
CREATE INDEX ON documents USING diskann (embedding vector_cosine_ops); SELECT * FROM documents ORDER BY embedding <=> $query_vector LIMIT 10;75% less cost on AWS
Statistical Binary Quantization
The Killer Feature
The real power is using both together. Combine the lexical precision of BM25 with the semantic understanding of vector embeddings—without leaving your database, without an external reranker, and without syncing data.
How RRF works
Run BM25 keyword search and vector similarity search in parallel, then fuse results using Reciprocal Rank Fusion. One database, one query layer, state-of-the-art retrieval quality.
-- BM25 keyword results WITH keyword_results AS ( SELECT id, ROW_NUMBER() OVER (ORDER BY content <@> 'search query') AS rank_kw FROM documents ORDER BY content <@> 'search query' LIMIT 20 ), -- Vector similarity results semantic_results AS ( SELECT id, ROW_NUMBER() OVER (ORDER BY embedding <=> $query_vec) AS rank_vec FROM documents ORDER BY embedding <=> $query_vec LIMIT 20 ) -- Reciprocal Rank Fusion SELECT COALESCE(k.id, s.id) AS id, COALESCE(1.0/(60 + k.rank_kw), 0) + COALESCE(1.0/(60 + s.rank_vec), 0) AS rrf_score FROM keyword_results k FULL OUTER JOIN semantic_results s ON k.id = s.id ORDER BY rrf_score DESC LIMIT 10; How RRF works
Run BM25 keyword search and vector similarity search in parallel, then fuse results using Reciprocal Rank Fusion. One database, one query layer, state-of-the-art retrieval quality.
BEGIN
TABLE
INSERT data
INDEX
UPDATE vector
COMMIT
atomic consistency
One system to operate
No ETL pipelines. No sync jobs. No eventual consistency. Insert a row and it's searchable.
ACID guarantees for search
Your search index participates in transactions. Rollback a write and the index rolls back with it.
Security you already have
Row-level security, roles, and permissions apply to search queries automatically.
Backups include everything
pg_dump, streaming replication, point-in-time recovery—your search indexes are just part of your database.
SQL you already know
No new query language. No client library. ORDER BY, LIMIT, WHERE, JOIN—search composes with everything else.