◀ Knowledge hub

02, Data & state

Search you already pay for, in Postgres

codeAmani Labs Engineering
Cinematic still for Search you already pay for, in Postgres

Most products do not need a search cluster

Reaching for a dedicated search engine is a reasonable instinct and usually a premature one. It is another service to run, another index to keep in sync, and another failure mode, and for a corpus of thousands or even tens of thousands of documents, Postgres full text search is fast, good, and already running.

How it works

Postgres turns text into a tsvector, a normalized list of lexemes with positions, and matches it against a tsquery. Add a generated column for the searchable text and an index on it, and you have ranked search with no new infrastructure.

alter table documents
  add column search tsvector
  generated always as (
    to_tsvector('english', title || ' ' || coalesce(body, ''))
  ) stored;

create index documents_search_idx on documents using gin (search);

The query ranks results by relevance and, crucially, lets you filter by your ordinary columns in the same statement:

select id, title, url,
       ts_rank(search, websearch_to_tsquery('english', $1)) as rank
from documents
where search @@ websearch_to_tsquery('english', $1)
  and doc_type = $2
order by rank desc
limit 10;

websearch_to_tsquery accepts the kind of input a user actually types, including quoted phrases and the word "or", so you are not parsing query syntax yourself.

Combine it with semantic search

Full text search nails exact terms, names, and codes. Semantic search over embeddings nails meaning and paraphrase. The strongest results come from running both and merging: keyword search for precision, vector search for recall. Both live in the same database (see the pgvector guide), so combining them is a query, not an integration.

When to graduate

If you reach very large corpora, demanding typo tolerance, faceting, and sub fifty millisecond latency at high query volume, a dedicated engine earns its keep. Until then, the search you already pay for is the search you should ship, and you can always add the engine later without having wasted anything.

Qualified conversation

Have a build to de-risk? Let's talk.

Tell us what you are building. We respond within two business days.