Tried weighted sum fusion first (0.6 * semantic + 0.4 * fulltext normalized) — results were dominated by the full-text score because tsvector ts_rank_cd outputs varied by orders of magnitude across queries. Switched to RRF with k=60 (rank-based, score-invariant): each engine's contribution is 1/(k + rank_i), summed per document. Qualitatively produced more relevant top-5 results on a 1k-entry corpus and is what the BM25-dense-hybrid literature converges on.
pgvector + PostgreSQL full-text search. k=60 is standard; sensitivity is low across 20–100.