Your Search Box Is Just SQL LIKE Wearing a Trench Coat
You built a little catalog app. Products, blog posts, a directory of self-hosted tools, doesn’t matter. At some point you added a search box, and under the hood it runs WHERE title ILIKE '%query%'. It works fine in the demo. Then a real user types “kubernets” instead of “kubernetes” and gets zero rows back, because Postgres LIKE doesn’t know what a typo is and doesn’t care that it hurt your feelings.
That’s the gap Meilisearch and Typesense both fill: typo-tolerant, ranked, sub-50ms search you run yourself instead of paying an Algolia bill. I set both up side by side, indexed the same data into each, and ran the same misspelled query against both. My take: pick Typesense when your data has a real schema, you want facets and filters to feel native, and you might grow into a self-hosted cluster. Pick Meilisearch when you want zero schema ceremony, your dataset is disk-friendly rather than RAM-hungry, and you’d rather spend five minutes on setup than five minutes reading a field-type reference.
Full example: Clone the working files at github.com/KingPin/sumguy-examples/tree/main/self-hosting/meilisearch-vs-typesense
Neither one is Elasticsearch. That’s the point. No JVM, no cluster of shard replicas to babysit at 2 AM, no mapping explosion because someone indexed a field with 40,000 unique values. Both ship as a single binary with a Docker image, both answer in single-digit milliseconds on a laptop, and both are pleasant to run compared to the alternative.
Getting Both Running in Under a Minute
Here’s the Compose file that runs them side by side, using the versions current as of September 2026: Meilisearch v1.54.0 (released 2026-09-21, per the GitHub release) and Typesense v30.2 (released 2026-04-19, per the GitHub release).
services: meilisearch: image: getmeili/meilisearch:v1.54.0 restart: unless-stopped environment: MEILI_MASTER_KEY: "change-me-master-key" MEILI_ENV: "development" ports: - "7700:7700" volumes: - meili_data:/meili_data
typesense: image: typesense/typesense:30.2 restart: unless-stopped command: '--data-dir /data --api-key=change-me-typesense-key --enable-cors' ports: - "8108:8108" volumes: - typesense_data:/data
volumes: meili_data: typesense_data:Notice the asymmetry already. Meilisearch’s docs lead with environment variables (MEILI_MASTER_KEY, MEILI_ENV), the pattern every Docker person already knows. Typesense’s docs lead with CLI flags, so this Compose file passes them in command:. Typesense also reads the same settings as environment variables: prefix the flag name with TYPESENSE_ and use caps and underscores, so --api-key becomes TYPESENSE_API_KEY. Pick one style per service and stick with it.
MEILI_ENV matters more than it looks. Set to development, a master key is optional and the search preview UI at http://localhost:7700 is enabled. Set to production, a master key of at least 16 bytes becomes mandatory (Meilisearch refuses to boot without one) and the preview UI is disabled. Use development for this demo, flip it before anything touches the public internet.
Typesense has no equivalent web UI bundled in the open-source server. You talk to it over the REST API or point a client SDK at it. That’s a real trade-off if you wanted a quick way to eyeball your index without writing a query.
Schema or No Schema: The First Real Difference
This is the one that decides which engine fits your project before you write a single line of app code.
Typesense wants a schema up front:
{ "name": "movies", "fields": [ {"name": "title", "type": "string"}, {"name": "director", "type": "string", "facet": true}, {"name": "year", "type": "int32"}, {"name": "genre", "type": "string", "facet": true}, {"name": "rating", "type": "float"} ]}Send a document with a field that doesn’t match this schema, or the wrong type, and Typesense rejects it. That’s not a limitation, it’s the feature. You get compile-time-style guarantees on your search index, which is exactly what you want for a product catalog where price had better always be a number. Typesense also supports auto-schema detection with a wildcard field ({"name": ".*", "type": "auto"}), which infers types from the first documents it sees. Useful for prototyping, but you lose the strict-typing safety net an explicit schema exists to give you.
Meilisearch skips this step entirely. Send it a JSON document, it indexes every field, done:
curl -X POST 'http://localhost:7700/indexes/movies/documents?primaryKey=id' \ -H 'Authorization: Bearer change-me-master-key' \ -H 'Content-Type: application/json' \ --data-binary @movies.jsonNo schema means no rejected documents and no migration step when your data shape changes. It also means no compile-time guarantee that rating is always a float, which is a real cost if your data pipeline is sloppy. Schemaless is a convenience you’re borrowing against future debugging time. For a blog, a docs site, or a changelog, that trade is easy. For a marketplace with a strict price and inventory model, Typesense’s rejection-on-bad-type behavior will save you from shipping a bug where "price": "N/A" silently breaks your sort order.
Where Your Data Actually Lives: RAM vs Disk
Storage decides what hardware you need, and the two engines made opposite bets on it.
Meilisearch stores everything in LMDB, a memory-mapped, disk-backed key-value store. Meilisearch’s own docs measure this against their public movies.json demo dataset (8.6MB of JSON, 19,553 documents): after indexing, the on-disk LMDB size comes out to roughly 122MB. The docs are explicit that Meilisearch performs best when the whole dataset fits in RAM, but also state that a RAM-to-disk ratio around 1/3 does not materially hurt performance, and many workloads run fine at around 1/10. Translation: Meilisearch degrades gracefully when your server doesn’t have enough memory to hold everything, because the OS page cache does the heavy lifting and LMDB just reads from disk when it has to.
Typesense takes the opposite bet. Per its own system requirements guide, it keeps the entire search index in RAM and a copy of the raw data on disk. The rule of thumb is 2 to 3 times the size of your searchable fields in RAM, counting only fields you actually query on, not fields you just display. Vector fields cost roughly 7 bytes per dimension per record on top of that, and if you turn on Typesense’s built-in embedding models for semantic search, budget another 2 to 6GB just for the model weights.
Neither number is a benchmark I ran, both are the vendors’ own published figures, cited as such. The practical upshot: if you’re running search on a Raspberry Pi or a cramped VPS with a small dataset that’s mostly text you rarely touch, Meilisearch’s disk-friendly design is kinder to your RAM budget. If your dataset is small enough to comfortably fit in memory and you want the fastest possible filtered and faceted queries, Typesense’s in-memory model is built for exactly that.
Typo Tolerance Without Reading a Manual
Both engines correct typos by default, no configuration needed, which is the entire reason either one beats LIKE '%query%'.
Meilisearch’s defaults: words of 1 to 4 characters need an exact match, words of 5 to 8 characters tolerate 1 typo, words of 9 or more characters tolerate up to 2 typos. A typo in the first character of a word counts double, so short words with a leading typo won’t match.
Typesense’s defaults: num_typos is 2 across all searched fields, but it only kicks in past a minimum word length. min_len_1typo defaults to 4 characters, min_len_2typo defaults to 7.
I ran the same deliberately mangled query, Forklyft Dreems, against both engines after indexing the same 20-record movie dataset (the full script is in the companion repo linked above). Both returned “Forklift Dreams” as the top hit, no configuration changed on either side:
python3 load_and_query.py[Meilisearch] query='Forklyft Dreems' processingTimeMs=0 - Forklift Dreams (2021, Comedy)
[Typesense] query='Forklyft Dreems' search_time_ms=0 - Forklift Dreams (2021, Comedy)Both came back in near-zero milliseconds on a warm 20-document index running on a laptop (the first cold run reported 5ms and 1ms), which tells you nothing about performance at scale but confirms the typo correction works out of the box on both engines without you touching a single relevancy setting.
Scaling Out: Clustering vs the Enterprise Upsell
The two projects’ business models show through the docs on this one.
Typesense ships Raft-based clustering in the open-source, self-hosted build. You configure a nodes file listing each node’s peering address and API port, and Typesense elects a leader, replicates writes, and serves reads from any node. A 3-node cluster tolerates 1 node failure, a 5-node cluster tolerates 2, at the cost of slightly higher write latency as cluster size grows. You wire this up yourself, there’s no managed control plane unless you pay for Typesense Cloud, but the clustering code itself isn’t gated behind a paywall.
Meilisearch’s self-hosted, MIT-licensed build does not include sharding or replication. Those live behind the Enterprise Edition, licensed under the Business Source License (more on that below), and Meilisearch’s own pricing page lists “distribute data across shards and replicas for high availability” as an Enterprise feature, not something the free build does. If you need Meilisearch to survive a node dying, your options are Enterprise licensing, Meilisearch Cloud, or rolling your own failover with periodic snapshots and a spare box on standby.
If self-hosted high availability across multiple machines matters to your project today, that’s a real point in Typesense’s favor. If you’re running a single instance for a blog or an internal tool and don’t need a cluster, this difference won’t touch you.
Vector and Hybrid Search: Both Do It, Differently
Both engines do semantic and hybrid search now, this isn’t a 2023-era gap anymore.
Meilisearch generates embeddings through an “embedder” you configure. Remote sources include OpenAI, Cohere, Mistral, Gemini, and any provider with a REST API. The huggingFace source downloads an open-source model and runs it locally inside Meilisearch, and you can also send embeddings you generate yourself. Meilisearch generates and stores embeddings for your documents automatically, then a hybrid search request blends keyword and vector results in one call. Vectors live in Hannoy, Meilisearch’s LMDB-backed HNSW library, so they sit on disk with the rest of the index.
Typesense runs vector search with an HNSW index over a float[] field with a declared num_dim, ranked by cosine similarity, and it can generate embeddings itself using built-in models (at the RAM cost mentioned earlier) instead of requiring a third-party API key. Hybrid search combines a keyword search on your text fields with a vector search on the embedding field and merges the two rankings with Rank Fusion, weighted 0.7 keyword to 0.3 vector by default, adjustable with an alpha parameter.
A remote embedder in Meilisearch costs you an API key (or your own embedding pipeline) but little extra RAM. A local huggingFace embedder in Meilisearch and Typesense’s built-in models both cost RAM and CPU but no external dependency. Pick based on which resource you have more of: a spare few dollars of API budget, or a spare few gigabytes of memory.
Licenses, Because Somebody Will Ask
Typesense is GPL-3.0, confirmed via its GitHub repository metadata. The entire project, including anything you’d call “enterprise” features elsewhere, ships under one open-source license.
Meilisearch is dual-licensed: the core engine is MIT, and the Enterprise Edition components (sharding and replication among them) are under an adapted Business Source License 1.1 (BUSL-1.1), per the license file in Meilisearch’s own repository. BUSL isn’t OSI-approved open source. Meilisearch’s grant allows the Enterprise code for testing, development, and evaluation only; production use needs a commercial license. Each version converts to MIT four years after publication. The core search engine you’d actually self-host stays MIT the whole time.
Practically: if you’re self-hosting either one for your own project without redistributing it as a competing product, the license difference doesn’t change what you can run today. It matters more if you’re building a product on top of one of these and reselling it, at which point read the actual license text, not a blog post about it.
Which One Should Run on Your Server
Run Typesense when your data has real structure (a product catalog, a job board, a directory with prices, dates, and categories you’ll filter on constantly), when faceted search is a core feature and not a nice-to-have, and when you want the option of a self-hosted multi-node cluster without an Enterprise contract. The schema-first approach will catch data bugs before your users do.
Run Meilisearch when your content is mostly free text (a blog, a wiki, documentation, a changelog), when you want to stand up search in one Docker command and never think about field types again, and when your hardware budget is tighter on RAM than on disk. It’s the search engine you reach for when “good enough, fast, and simple” beats “maximally tunable.”
Both exist as paid managed services too. Meilisearch Cloud and Typesense Cloud are real products if you’d rather not run the container yourself, both are paid tiers on top of the free self-hosted core, and neither vendor publishes pricing you should quote from memory since it changes. Check the current pricing page before you commit to either, same as you’d check any vendor’s checkout page instead of trusting what you remember from six months ago.
For most self-hosted blogs and docs sites, my money’s on Meilisearch: less setup, kinder to a small VPS, and you’ll never write a schema migration for your search index. For anything that looks like a real product catalog with filters your users actually rely on, Typesense’s explicit schema and built-in clustering earn their extra five minutes of setup.
Common Questions
Can I migrate data between Meilisearch and Typesense?
No automatic migration tool exists between Meilisearch and Typesense. Both expose plain REST APIs and accept JSON documents, so a short script that reads from one and bulk-imports into the other covers most cases. The real work is translating Typesense’s explicit schema into Meilisearch’s schemaless model, or writing a schema for a Meilisearch dataset going the other way.
Do I need Meilisearch or Typesense instead of Postgres full-text search?
Yes, if you need typo tolerance, sub-50ms ranked results, or faceted filtering, none of which Postgres tsvector does well out of the box. No, if your dataset is small, your users rarely search, and exact-match ILIKE or a basic tsvector column already meets your needs. Add a dedicated search engine when search becomes a feature people rely on, not before.
How much RAM do I need to self-host Typesense?
Budget roughly 2 to 3 times the size of your searchable fields in RAM, per Typesense’s own system requirements guide, counting only fields you query on, not display-only fields. A 500MB searchable dataset needs 1 to 1.5GB of RAM at minimum. Add 2 to 6GB more if you enable Typesense’s built-in embedding models for semantic search.
Does Meilisearch need less RAM than Typesense?
Usually yes, because Meilisearch memory-maps its LMDB data from disk instead of holding the full index in RAM. Meilisearch’s docs report good performance at a RAM-to-disk ratio of 1/10 for many workloads. Typesense keeps the whole searchable index in RAM at 2 to 3 times its size, so Meilisearch is the lighter option on small servers.
Is Typesense open-source clustering really free?
Yes. Typesense’s Raft-based high-availability clustering ships in the GPL-3.0 open-source build, not gated behind a paid tier. You configure and operate the cluster yourself using a manually maintained nodes file. Typesense Cloud automates that setup for you, but the underlying clustering code is available in self-hosted Typesense at no cost.