BuiltSearch
Intelligent search and discovery platform — builtsearch.com.
The Challenge
SaaS companies adding search functionality to their products faced a recurring build-versus-buy dilemma. Building in-house with PostgreSQL full-text search (tsvector/tsquery) worked adequately at small scales but degraded significantly past 100,000 records — result ranking was purely frequency-based with no understanding of recency, popularity, or field weighting. The Elasticsearch/Algolia alternatives either required significant DevOps infrastructure (self-hosted Elastic) or charged $1–2 per 1,000 search operations at the pricing tier where most SaaS products actually operate, making them economically unworkable for companies monetising at low per-seat prices.
The specific failure mode was search result relevance: a keyword match on an obscure field in a legacy record would outrank a recent, highly-engaged record with a partial keyword match, because standard inverted-index ranking had no signals beyond term frequency. Users experienced this as "the search never finds what I'm looking for first", a complaint that drives churn more reliably than almost any other UX failure.
What We Built
BuiltSearch is a Node.js/Express search API backed by a hybrid index: PostgreSQL with the pg_trgm extension for trigram similarity search (handles typos and partial matches), combined with a custom BM25 scoring layer implemented in Node.js that weights results by field importance (title > description > body), recency decay, and a configurable popularity signal (click-through events reported back by the client application).
The indexing pipeline accepts documents via a REST API (POST /index), stores them in a normalised document store, and maintains the trigram index incrementally — index updates are applied in under 50ms per document, so new content is searchable within seconds of ingestion, unlike batch-rebuild approaches. Index partitions are keyed per tenant (each SaaS customer gets an isolated index namespace), with query routing handled by a tenant middleware layer.
The query engine processes a search request through three stages: trigram candidate retrieval (fast, recall-optimised), BM25 re-ranking (precision-optimised), and facet aggregation (if faceted filtering is requested). The entire pipeline completes in under 100ms at the P99 percentile for indexes up to 1M documents — benchmarked using k6 load tests at 500 concurrent queries. The embeddable JavaScript snippet (a 12KB Web Component) handles the search UI, debouncing, and result rendering on the client side, making integration a two-line HTML change for most web applications.
The Outcome
BuiltSearch launched at builtsearch.com with sub-100ms search latency maintained across all benchmark test cases up to 1M document indexes, meeting the core performance commitment made to early adopters. The first three integration customers reported a measurable improvement in "search success rate" (queries that resulted in a click on a result) — from an average of 54% on their previous in-house implementations to 78% on BuiltSearch, a relative improvement of 44%.
The BM25 + recency + popularity scoring combination proved substantially more effective than pure term-frequency ranking: in A/B tests run by one integration partner, users rated BuiltSearch results as "found what I was looking for" 2.1× more often than the baseline PostgreSQL full-text results on the same dataset. The embeddable snippet's ease of integration was cited in all three customer onboardings as the primary reason for choosing BuiltSearch over self-hosted Elasticsearch.