If you're indexing thousands of records and reaching for queries, you're leaving performance on the table. Here's how to wire up PostgreSQL's full-text search with GIN indexes to cut query times from seconds to single-digit milliseconds.
This pattern powers the Mr. Technology skills scanner — 71k+ skills indexed and searchable in real-time.
and do sequential scans. On 70k rows, that's a full table scan every query. Fine for a prototype. Catastrophic at scale.
PostgreSQL has built-in full-text search. It works in two steps:
lets you rank matches — name matches rank higher than tag matches. tokenizes and stems the text.
avoids locking the table during index build. On 71k rows this takes a few seconds. On 7M rows, still under a minute.
is the match operator. orders results by relevance.
Standard doesn't do prefix matching out of the box. For autocomplete, use with trailing wildcards, or a separate trigram index:
Combine both for full-text + autocomplete.
| Approach | 71k rows |
|---|---|
| ILIKE | ~800ms |
| tsvector + GIN | ~3ms |
|---|---|
| Improvement | **266x faster** |