cat typesense-vs-elasticsearch-entity-search.md
Typesense vs Elasticsearch: picking a search engine for entity search
2026-05-06
I needed search over entities: companies, portfolios, and metrics. Someone types relianc and expects Reliance Industries, immediately, without having thought about spelling. That's a narrower problem than "search," and the narrowness is what made the choice interesting.
I picked Typesense. Here's the honest reasoning, including where Elasticsearch is still the right answer.
These engines optimise for different problems
The framing that helped me most: Elasticsearch is a distributed document store with search capabilities, while Typesense is a search engine with a deliberately small surface area.
Elasticsearch descends from Lucene and inherits its ambitions — aggregations, nested documents, percolation, log analytics, vector search, an entire observability stack. It'll do almost anything, and the price is that you must configure almost everything.
Typesense makes a narrower bet: typo tolerance and sub-second results out of the box, with defaults tuned for the case where a human is typing into a box and expecting instant feedback.
For entity search, that narrower bet is a near-perfect fit.
Typo tolerance you don't have to build
This decided it. Users misspell company names constantly, and in Typesense typo tolerance is simply on:
{
"name": "companies",
"fields": [
{ "name": "name", "type": "string" },
{ "name": "ticker", "type": "string" },
{ "name": "sector", "type": "string", "facet": true },
{ "name": "aum", "type": "float" }
],
"default_sorting_field": "aum"
}
Query relianc and you get Reliance. No analyzer chain, no fuzzy query DSL, no tuning fuzziness: AUTO and discovering it doesn't apply to your keyword field.
The equivalent in Elasticsearch is entirely achievable — a custom analyzer, an edge n-gram tokenizer, a multi_match with fuzziness, and careful field mapping. It's a known recipe. But it's a recipe you own, tune, and debug. Compare the shapes:
// Elasticsearch: expressive, and you maintain all of it
{
"query": {
"multi_match": {
"query": "relianc",
"fields": ["name^3", "ticker^2", "sector"],
"fuzziness": "AUTO",
"prefix_length": 1
}
}
}
# Typesense: the defaults are the feature
curl "localhost:8108/collections/companies/documents/search\
?q=relianc&query_by=name,ticker,sector&query_by_weights=3,2,1"
Both work. One of them I have to keep thinking about.
Operational weight is a real cost
Elasticsearch is a JVM application, and running it well means caring about heap sizing, GC behaviour, shard counts, and the fact that shard count is fixed at index creation and expensive to change later. None of that is unreasonable — it's the cost of a system built to scale to petabytes.
Typesense is a single C++ binary with no JVM. Memory usage is more predictable because the working set is designed to sit in RAM. For a team where nobody's full-time job is search infrastructure, that difference compounds every week.
The constraint to understand up front: Typesense holds indexed data in memory. That's why it's fast and why capacity planning is straightforward — but it means your dataset should comfortably fit in RAM. For an entity catalogue of companies and portfolios, that's trivially true. For 40TB of logs, it's disqualifying.
When I'd still choose Elasticsearch
I'd switch back without hesitation for:
- Log and event analytics at volume. This is what the ELK stack exists for. Time-based indices, ILM policies, retention tiers — Typesense isn't trying to compete here.
- Complex aggregations and analytics. Elasticsearch's aggregation framework is genuinely powerful. Typesense faceting is comparatively basic.
- Datasets that exceed available RAM. Disk-backed storage is the deciding factor.
- Rich relevance engineering. If you need custom similarity scoring, script-based ranking, or
function_scoreon many signals, you want Lucene's depth. - An existing ELK investment. If your org already runs it and has the expertise, that's a legitimate reason on its own.
The general lesson
The right question wasn't "which engine is better." It was "which engine's defaults match my problem, so I write the least code that I later have to maintain?"
For instant, typo-tolerant lookup over a bounded set of entities, Typesense's defaults are the requirements. Choosing it meant the search layer became a component I configured rather than a subsystem I owned.
Picking the more capable tool isn't free. You pay for capability in configuration surface, and configuration surface is where production incidents come from.
Next: running Typesense on Kubernetes — the Docker and StatefulSet configuration that took this from laptop to cluster.