Tech Stack23 June 2026 · 9 min read

SaaS Search in 2026: Postgres FTS vs Algolia vs Typesense

Postgres FTS works until it doesn't. Here's the exact threshold where Typesense wins on relevance, what Algolia costs at scale, and how to isolate tenant search data safely.

SaaS Search in 2026: Postgres FTS vs Algolia vs Typesense

Every SaaS team building search makes the same decision in the wrong order.

They reach for Elasticsearch because that's the canonical answer, or wire up Algolia before testing whether Postgres could handle the workload. Or, most commonly, they bolt ILIKE '%query%' onto a text field, which works at a hundred records and produces a spinning cursor at a hundred thousand.

I've wired up search across enough real SaaS products that the failure modes are familiar. The split between "Postgres is fine" and "you need a dedicated engine" is narrower than most posts suggest, and far more specific than "just use Algolia."

This is the decision tree I actually use.

When is Postgres full-text search actually enough?

A close-up brutalist concrete architectural structure with interlocking rectangular panels and a vertical electric cyan beam descending through a central channel

Postgres FTS handles small-to-medium catalogs from your existing database, with zero new infrastructure to operate or fail.

The Supabase team benchmarked Postgres FTS against MeiliSearch, Typesense, and OpenSearch on a 32MB movie dataset. At that size, Postgres matched the dedicated engines on query latency. The result matters less as a performance claim and more as a scope claim: if your dataset fits in RAM and your query rate is in the hundreds per second or below, you do not need a dedicated engine. A tsvector column, a GIN index, and a plainto_tsquery call around your input is the whole implementation.

The use cases it covers well: internal admin search (staff searching patient names, looking up order records), simple keyword matching on structured fields (ticket subjects, article titles, project names), and any path where relevance ranking does not differentiate your product.

You've felt the limitation before. User types "invoce" and gets nothing back. Thursday afternoon, they open a support ticket: "Why does search not find anything when I type wrong?" Postgres FTS has no typo tolerance out of the box. pg_trgm adds similarity matching, but at the cost of adding and tuning another extension — complexity on top of a tool that was not designed for this problem.

The cliff is precise. You hit it when you need any of these:

  • Typo tolerance without installing additional extensions
  • Prefix/instant-as-you-type search returning results on every keystroke
  • Faceted filters with real-time counts updating as the user drills down
  • Ranking tuned to click-through or conversion signals
  • Languages that Postgres's bundled dictionaries do not cover (Japanese, Chinese, Korean)

When you're already running on Supabase + Stripe, to_tsvector + GIN index is an afternoon. For early-stage B2B SaaS where most tenants have under 50,000 records, this covers you well past your first paying customers. Build on it. Migrate when the gap shows up in your support queue, not before.

What does Typesense get right that Postgres FTS doesn't?

Two concrete slabs leaning against each other in a brutalist setting — the left slab rough and matte, the right slab smooth and luminous with a bright cyan reflection

Typesense gives you typo-tolerant, sub-50ms search with native faceting and a self-contained binary — no JVM, no heap tuning, no managed cloud required.

Let me back up on that "sub-50ms" claim. Typesense's C++ engine stores the entire index in RAM. Warm queries on a running node return almost immediately. Cold queries on a freshly rebooted node take longer. The in-memory model produces stable, predictable latency in steady-state production, but it also means your node needs enough RAM to hold the full index. Typesense describes its design target as "instant search-as-you-type for data sets that fit in RAM, up to 24 TB."

What you actually get over Postgres FTS:

  • Typo tolerance on by default — a user typing "resevation" gets "reservation" with zero configuration
  • Real prefix search: type "inv" and results update character by character
  • Field-level weighting without flattening everything into one tsvector
  • Faceting with counts returned at query time, not via a separate GROUP BY
  • Scoped API keys for per-tenant data isolation (more below)
  • Vector and semantic search since 26.x — hybrid keyword + semantic retrieval in one system

Have you been writing custom correction logic to paper over Postgres FTS limitations? That's the migration signal right there.

On MeiliSearch. It sits between Postgres FTS and Typesense on the complexity spectrum. Easy to self-host, has a clean admin dashboard, comparable typo tolerance. But it is single-node only as of mid-2026 — no native clustering, no fault tolerance. A search service that cannot survive a node failure without downtime is a liability in production SaaS. Typesense's RAFT-based multi-node clustering is the specific reason it is the self-hosted default for SaaS teams that need real uptime.

Algolia vs Typesense: Where the cost difference becomes real

A concrete scale balanced on a triangular fulcrum with a matte grey block on the left and a solid electric cyan block on the right against a brutalist backdrop

Algolia's free Build plan includes 1 million records and 10,000 searches per month. Past that free tier, the per-unit costs compound quickly.

| Metric | Algolia (Grow) | Typesense Cloud (4 GB) | Self-hosted Typesense | |--------|----------------|------------------------|----------------------| | Monthly base | Pay-as-you-go | ~$58/month | ~$25/month (VPS) | | Per 1K searches above free | $0.50 | Included in plan | Infrastructure only | | 5M searches/month (est.) | ~$2,500 | ~$58/month | ~$40/month | | Typo tolerance | ✅ | ✅ | ✅ | | Faceting with counts | ✅ | ✅ | ✅ | | AI recommendations | ✅ | ❌ | ❌ | | Visual merchandising dashboard | ✅ | ❌ | ❌ | | Self-hosted option | ❌ | ✅ | ✅ |

In October 2025, Algolia launched a Grow Plus tier adding AI synonyms, AI ranking, and advanced personalization to self-serve accounts. The per-search price on Grow Plus is $1.75 per 1,000 requests — 3.5x the base Grow rate. According to Algolia's announcement, the premium reflects inference cost on every query for running ML ranking models.

Algolia earns its price in one scenario: a merchandising team or an e-commerce catalog where AI ranking and click-through analytics directly drive conversion. Their globally distributed network handles over 1.75 trillion searches annually, and the 99.999% SLA is genuinely enterprise-grade — not a marketing number. That reliability matters when search downtime means lost revenue at scale.

For most multi-tenant SaaS tools in B2B — project management, clinic software, property management, CRM — those capabilities do not apply. You do not have a merchandising team. Search is not a conversion lever where AI ranking moves the needle. In that case, Typesense at $58/month for a production node is the better spend by a wide margin.

Multi-tenant search isolation: the part most tutorials skip

In multi-tenant SaaS, tenant A must never see tenant B's records in search results — no exceptions, no edge cases where a partial leak is acceptable.

This isolation is structural with Postgres FTS. Every query has a WHERE tenant_id = $1 filter. RLS policies on Supabase enforce it at the database level. You cannot accidentally break it without also breaking the query entirely.

With a dedicated search engine, you build the isolation explicitly. Three patterns, in ascending order of operational overhead:

  1. Shared collection with scoped API keys. Store all tenants' data in one Typesense collection, embed a filter_by=tenant_id:=<id> constraint inside an HMAC-signed scoped key, generate one per tenant at onboarding. Typesense cryptographically enforces the filter — the user cannot override it client-side, even with the key. Algolia offers the equivalent under the name Secured API Keys. This is the right default for most B2B SaaS with up to thousands of tenants.

  2. Separate collection per tenant. Hard isolation, simpler mental model, more schema management overhead. At a dozen tenants, invisible. At ten thousand tenants, you need automated collection provisioning and a migration playbook that runs across all collections simultaneously.

  3. Separate cluster per tenant. Full isolation for regulated industries where contractual data-residency requirements apply. Cost scales linearly with tenant count — only justifiable for high-value enterprise accounts.

On Callidus, the multi-tenant clinic SaaS I built solo between February and April 2026, patient records live under tenants/{tenantId}/... in Firestore with isolation enforced through Firebase Security Rules and JWT claims. Callidus runs React + Firebase + Stripe Connect — not Postgres — so the FTS vs Typesense decision didn't arise directly. But the isolation requirement was identical. Every record query is scoped by tenantId. Fourteen clinics onboarded. Zero cross-tenant data issues.

BookBed, a Flutter + Firebase multi-tenant property management SaaS, followed the same pattern: Firestore queries scoped by tenant, no dedicated search engine at launch.

The rule I've landed on: use structural isolation — Postgres WHERE clauses or Firestore security rules — while you can get away with it. Add a dedicated engine with scoped keys when customer-facing search quality becomes the documented reason people churn.

Ranking signals most SaaS products ship without

Default Postgres ts_rank sorts by text relevance. Adequate for internal tooling. Not enough for customer-facing search where result quality is a surface users evaluate every session.

Three signals worth adding, ordered by implementation effort:

  1. Recency. Prefer newer records when relevance scores are close. In Typesense: a sort_by expression combining _text_match with created_at. In Postgres: a manual expression in ORDER BY.

  2. Popularity. Weight results by view or click count. In Typesense: embed as a numeric field, reference in the sort expression. In Algolia: tracked automatically via analytics and fed back into ranking — one concrete thing Algolia's analytics pipeline does that Typesense does not replicate natively.

  3. Field weighting. A title match should rank above a description match. In Typesense: per-field weights in the collection schema. In Postgres: setweight() on concatenated tsvectors works, but collapses field boundaries and prevents independent field-level querying.

Faceting performance is the less-discussed scaling concern. Facets on a 50,000-record Typesense collection return sub-100ms with counts included in the same query. On Postgres, equivalent facet queries use GROUP BY and compete directly with your OLTP write load on the same connection pool. A workload separation decision, not a raw capability gap — but one that matters at production traffic levels.


The practical next step: run EXPLAIN ANALYZE on your current search query. Count your indexed records. Then type a misspelled version of a common search term into your own product. If Postgres returns nothing — or if you have correction logic already patching that gap — that's the migration signal. Typesense setup is an afternoon. The scoped-key multi-tenant isolation pattern is another half-day. Start there before evaluating Algolia.

DL

Dusko Licanin

Full-Stack Developer · Banja Luka, Bosnia

Full-stack developer shipping SaaS MVPs, web apps, and mobile apps 2× faster than agencies using AI-augmented workflows. Live portfolio: BookBed, Callidus, Pizzeria Bestek.

Frequently Asked Questions

When should a SaaS startup move from Postgres FTS to a dedicated search engine?

Move when Postgres FTS forces you to write workaround code for typos, prefix queries, or real-time facets — those workarounds signal a tool mismatch, not a query tuning problem. The practical trigger is usually between 100,000 and 2 million records, though the actual signal is feature need, not document count alone. A [2025 Supabase benchmark](https://supabase.com/blog/postgres-full-text-search-vs-the-rest) confirmed Postgres FTS matches dedicated engines at small dataset sizes — use that window to focus on product, then migrate when the feature gap shows up in support tickets. Typesense setup is an afternoon; the multi-tenant scoped key pattern adds another half-day.

Is Typesense or MeiliSearch better for self-hosted SaaS search in 2026?

Typesense is the better choice for production SaaS because it supports RAFT-based clustering, letting three nodes survive an individual node failure without downtime. MeiliSearch remains single-node only as of mid-2026, which makes it unsuitable as a production SaaS search layer where uptime is a product expectation. Both use a simple REST API and have comparable typo tolerance and latency on small datasets. MeiliSearch has a slightly more polished admin dashboard, which can matter for non-technical stakeholders — but for a SaaS where search is customer-facing, fault tolerance outweighs dashboard polish. If you're prototyping or building an internal tool with acceptable restart downtime, MeiliSearch is fine. For production customer-facing search, Typesense is the pick.

How do you implement multi-tenant search isolation in Typesense?

Use scoped API keys: generate a search-only parent key, then derive per-tenant keys by embedding a `filter_by=tenant_id:=<id>` constraint into an HMAC digest. Hand the scoped key to the frontend at session start. Typesense cryptographically enforces the filter — the user cannot override it client-side, even if the key is visible in browser network requests. This means you can expose the key in a JavaScript frontend without risk of cross-tenant data leakage. Generate scoped keys server-side at onboarding and rotate them on tenant deactivation. Algolia offers an equivalent mechanism called Secured API Keys using the same HMAC model. For regulated industries or high-value enterprise accounts, consider separate collections per tenant or a dedicated Typesense cluster for the strictest contractual isolation.

What did Algolia's Grow Plus pricing change in October 2025?

Algolia launched the Grow Plus tier in October 2025, adding AI synonyms, AI ranking, query categorization, and advanced personalization to self-serve accounts. The [per-search price increases from $0.50 to $1.75 per 1,000 requests](https://www.algolia.com/about/news/algolia-expands-pricing-plans-to-bring-ai-search-capabilities-to-every-developer) — a 3.5x premium for AI features. For B2B SaaS without an e-commerce catalog or dedicated merchandising team, the base Grow tier or Typesense is almost certainly the better value. Grow Plus makes sense if you're building consumer-facing search where ML ranking quality demonstrably drives conversion or where a non-technical team needs to tune results through a visual dashboard without writing code.

Can you migrate from Postgres FTS to Typesense without rebuilding your data model?

Yes — Typesense acts as a search read replica alongside your Postgres source of truth, and the migration is additive rather than replacing anything. Keep Postgres as the write layer and sync records to Typesense via webhooks or a scheduled job that pushes Postgres writes to the Typesense collection. The one thing to design upfront: ensure tenant IDs and record IDs are consistent across both systems from day one, so the `filter_by=tenant_id` scoped key pattern maps cleanly to your existing `tenant_id` column. The Typesense collection schema defines which fields are searchable, sortable, and facetable — it's a projection of your Postgres data, not a replacement. You can roll back to Postgres FTS at any time by stopping the sync job.