Self-hosted search in 2026: revisit Meilisearch, Typesense and Manticore Search before you add another search box
Picture an electrical and hardware distributor headquartered in Vadodara, with warehouses in Anand, Bharuch, Godhra, Rajkot and Surat (an invented example, not a real client). About 20,000 products, from LED bulbs and ceiling fans to MCBs, copper wire, conduit and pumps. Around four hundred dealers order through a web and Android app, and product search is a PostgreSQL ILIKE '%term%' on the name. Dealers type the way people type on a phone in a shop: “celing fan”, “submersable pump”, “mcb 32a”, or a five-digit code read off a box. Most of those searches return nothing, and the order moves to WhatsApp.
The product owner wants search-as-you-type with typo tolerance, filters with counts for brand, category, price and stock, “nearest warehouse” sorting, and one rule that cannot break: each dealer sees only the products in their own agreement. The team is two backend developers and one person who also looks after the servers. Elasticsearch and OpenSearch were ruled out as too much engine for 20,000 documents and that team (the fork itself is covered in the Elasticsearch and OpenSearch post). Three proposals arrive. The frontend developer wants Meilisearch. A backend developer who used it at a previous job wants Typesense. The person who ran Sphinx years ago wants Manticore Search, because it speaks SQL.
This post compares those three as they stand on 19 October 2026: licence history, governance, architecture, matching and counting behaviour, facets and filters, multi-tenant keys, operations, security and maintainer health. Managed services and dedicated vector databases are out of scope. The question is what each engine does with the same messy query, and what it takes to keep it running.
Facts come from GitHub releases and LICENSE history, official docs and changelogs, CVE records, GitHub advisories and OSV, and a drill that loaded one invented catalogue into Meilisearch 1.55.0, Typesense 30.2 and Manticore Search 29.9.0 on one shared box. It is not a speed benchmark, and nothing here is legal advice.
The short version
- Typo tolerance is three different rule sets, and hit counts mean three different things. All three found “celing fan” and “submersable pump”. “led bulp” returned 4,730 hits on Meilisearch and 1,151 on Typesense and on Manticore with fuzzy search, because Meilisearch allows no typo in a four-letter word and by default counts documents matching only some words.
- Facets and filters agreed exactly when the hit set was the same: category counts, price, boolean, array and geo filters. Differences came from matching, not faceting.
- Meilisearch 1.55.0 (12 October 2026) is MIT for the Community Edition, but since v1.19.0 (August 2025) some features are Enterprise Edition under BUSL 1.1. Replication and sharding are among them, so the free edition has no built-in high availability.
- Typesense 30.2 (19 April 2026) is GPL-3.0, keeps the whole index in RAM, and has Raft clustering in the open-source server. Its 31.0 candidates reached RC20 on 13 October 2026, but there has been no stable release for six months.
- Manticore Search 29.9.0 (11 September 2026) is a 2017 fork of Sphinx, GPLv3-or-later since 6.3.0 (May 2024), with SQL, Galera replication and, since 27.0, opt-in authentication. Permissions are per table, not per row, and its fuzzy search gave the most false positives.
- Security: published CVEs exist for Typesense (two, fixed in 29.1 and 30.2) and Manticore (one, fixed in 28.4.4). Meilisearch has fixed several issues in 2026 release notes, including two it names as CVEs that the CVE list did not yet contain on 19 October.
Where things stand on 19 October 2026
Dates are GitHub release published_at converted from UTC to IST (UTC+5:30); the Typesense release candidate date is the Docker Hub tag’s last_updated. Licences are from the LICENSE files in each repository.
Project
Release
Date (IST)
Notes
Licence
Meilisearch (meilisearch/meilisearch)
v1.55.0
12 October 2026, 2:51 PM
Latest; inline dynamic search rules (EE only)
MIT (CE); BUSL 1.1 for EE parts
Meilisearch
v1.54.3, v1.53.3, v1.52.4
1 October 2026, 3:24 PM to 3:48 PM
Stability fix backported to three minor lines
Same
Typesense (typesense/typesense)
v30.2
19 April 2026, 9:30 PM
Latest stable; fixes CVE-2026-47216 and CVE-2026-47225
GPL-3.0
Typesense
v29.1
19 April 2026, 9:29 PM
Same two fixes for the 29 line
GPL-3.0
Typesense
31.0.rc20
13 October 2026, 4:34 PM
Docker image only; not a GitHub release
GPL-3.0
Manticore Search (manticoresoftware/manticoresearch)
29.9.0
11 September 2026, 7:50 PM
Latest; bundles Buddy 4.4.3, MCL 14.2.1, backup 1.11.0
GPLv3-or-later
Manticore Search
28.4.4
10 July 2026, 8:11 PM
First release with the CVE-2026-92796 fix
GPLv3-or-later
Manticore Columnar Library
14.2.1
Bundled with 29.9.0
Columnar storage, secondary indexes, KNN
Apache 2.0
GitHub stars on 19 October 2026: Meilisearch about 59,596, Typesense about 27,002, Manticore about 12,060. Open issues: 322, 911 and 651. Stars measure attention, not fitness for your catalogue.
Timeline
Date (IST)
Event
6 July 2017
Manticore Search 2.3.3, the first entry in its changelog, after forking Sphinx 2.3.2
29 January 2018
GPL v2 licence file added to the Typesense repository
12 November 2019
Meilisearch drops the Commons Clause and becomes plain MIT
30 March 2020
Typesense licence text updated to GPL v3
6 February 2023
Meilisearch v1.0.0
2 April 2024
Typesense drops 0.x numbering: 0.25 is followed by 26.0
23 May 2024
Manticore 6.3.0 changes the licence from GPLv2-or-later to GPLv3-or-later
30 January 2025
Manticore 7.0.0; from here each breaking change bumps the major number
25 August 2025
Meilisearch v1.19.0: sharding as the first Enterprise Edition feature under BUSL 1.1
2 March 2026
Meilisearch v1.37.0: replicated sharding, Enterprise Edition only
19 April 2026
Typesense 30.2 and 29.1
19 June 2026
Manticore 27.1.5 round-up: authentication and authorisation (from 27.0.0), sharded tables
11 September 2026
Manticore 29.9.0
17 September 2026
CVE-2026-92796 (Manticore) published
12 October 2026
Meilisearch v1.55.0
First question: what should the search box promise?
“We need typo-tolerant search” is a wish, not a specification. Before comparing engines, write the promise in one sentence and get the product owner to sign it:
For [these query types: product names, codes, brands, partial words], a dealer should find [the right product in the top N] even with [one or two typos, missing letters, wrong spacing], must never see [products outside their agreement], and the filter counts must [match the results shown]. We can rebuild the index from [source of truth] in [minutes] and keep search up through [one node failure, or not].
Then separate three layers, because the engines differ at each one:
- Matching rules. Which words may have typos and how many, whether the last word is a prefix, whether all words must match, and how codes are tokenised.
- Counting rules. What “number of results” means. Counting documents that match half the query is a different promise from counting full matches.
- Operating rules. RAM or disk, restart, backup and restore, upgrades, and who can query what.
What each engine actually is
Meilisearch 1.55.0
Meilisearch started in 2018 as MeiliDB, written in Rust by Meili SAS. Its LICENSE in October 2019 was MIT plus the Commons Clause, which withholds the right to sell the software; a commit on 12 November 2019 made it plain MIT. Version 1.0 came in February 2023. In 2026 it has shipped 52 releases, 24 of them new minor versions, about one every two weeks.
The licence changed again in 2025. The root LICENSE now says parts of the work are the Meilisearch Enterprise Edition (EE) under the Business Source License 1.1 and the rest is MIT (MIT AND BUSL-1.1). The adapted BUSL allows EE code for non-production use only and converts to MIT four years after each version is published. The steps:
- v1.19.0 (August 2025): sharding, the first EE feature.
- v1.28.0 (December 2025): separate binaries. The default binary stays MIT; files with “enterprise” in the name are EE.
- v1.31.0 (December 2025): S3-streaming snapshots move from Community to Enterprise, a breaking change; on-disk snapshots stay in Community.
- v1.37.0 (March 2026): replicated sharding, also EE.
The docs are not fully in step (the editions page names only sharding; the README also lists S3-streaming snapshots and search rule previews), so read the release notes for your version.
The architecture is simple: one binary, storage in LMDB (a memory-mapped key-value store), and an asynchronous task queue that returns a task id for every write. Documents have no fixed schema; filterable and sortable attributes are index settings. Typo tolerance is on by default: none for words up to four characters, one from five, two from nine, and numbers too unless you set disableOnNumbers. The default matchingStrategy is last: documents matching all words come first, then words are dropped from the end of the query to find more. Hybrid search, geo search, facets and tenant tokens (signed JWTs that carry filters) are in the Community Edition.
Two defaults to know: the default environment is development, which runs without a master key, and telemetry is on unless you pass --no-analytics. In production it refused to start without a master key of at least 16 bytes.
Typesense 30.2
Typesense is written in C++ and calls itself an open-source alternative to Algolia and an easier alternative to Elasticsearch. The repository dates from January 2017; a GPL v2 licence went in on 29 January 2018 and became GPL v3 on 30 March 2020. The README explains why GPL and not AGPL: the server runs as a separate process, and AGPL would make network access a trigger for sharing modifications.
The design choice that matters most is memory. Typesense keeps the entire search index in RAM and the raw documents on disk in RocksDB; its sizing guide says two to three times the size of the searchable fields. On restart it rebuilds the index from disk, so restart time grows with data. High availability is in the open-source server: Raft, at least three nodes to survive one failure, writes forwarded to the leader.
Matching is set per query. Defaults include num_typos 2, min_len_1typo 4, min_len_2typo 7, prefix on the last word, and two thresholds that surprise people: typo_tokens_threshold 1 (look for typo corrections only if fewer than one result was found) and drop_tokens_threshold 1 (drop words only if nothing matched). Collections have a declared schema, which also holds tokenisation options such as token_separators. Scoped search keys embed parameters such as filter_by, signed with HMAC, that the user cannot override. Vector and hybrid search, JOINs, synonyms and curation are all in the open-source server.
Releases are few and large. In April 2024 the project dropped 0.x numbering (0.25.2 was followed by 26.0); nine stable releases have followed, the latest on 19 April 2026. The 31.0 line has been in release candidates on Docker Hub since at least August 2026, with RC20 on 13 October, and main had commits that week. The server configuration reference documents no telemetry setting, and the default --api-address is 0.0.0.0.
Manticore Search 29.9.0
Manticore’s README says it was forked from Sphinx 2.3.2 in 2017; the binary still prints Sphinx copyright lines from 2001 to 2016. The licence was GPLv2-or-later until 6.3.0 (23 May 2024) made it GPLv3-or-later. The bundled Manticore Columnar Library is Apache 2.0, and Manticore Buddy, the PHP sidecar behind fuzzy search, autocomplete, backups and sharding commands, is GPL-3.0.
Version numbers need a note. 29.9.0 is only twenty months after 7.0.0 (January 2025): the release notes tie each new major number (18.0.0, 19.0.0, 21.0.0 and so on) to a breaking change. The 25.0.0 notes list seven since 18.0.0, including two index format bumps, and older versions cannot open indexes written in format 69, so downgrades need planning. Since 25.0.0 the manticore package bundles Buddy, MCL, backup and Galera.
It is the most database-like of the three: SQL over the MySQL protocol, a JSON HTTP API and Elasticsearch-compatible writes. Real-time tables keep a RAM chunk, disk chunks and a binlog. Replication uses Galera, described as virtually synchronous multi-master; native sharded tables came in 26.1.0. Authentication arrived in 27.0.0: off by default, enabled with auth = 1, with grants for read, write, schema, backup, replication and admin on tables or wildcards. There is no row-level rule.
Matching follows its Sphinx roots. Without operators, SQL MATCH() requires all words while JSON match defaults to OR, as the manual notes. Typo tolerance is off by default: fuzzy search is an option (OPTION fuzzy=1) handled by Buddy, needs min_infix_len on the table, and allows two typos per word by default. Telemetry is on unless you set telemetry = 0. The README’s speed claims against Elasticsearch and MySQL are the vendor’s own runs, and I have not used them.
Comparison tables
Cells without a primary source say “Not documented”.
Licence, governance and maintainer health
Meilisearch
Typesense
Manticore Search
Licence
MIT (CE); BUSL 1.1 for EE parts, MIT after four years per version
GPL-3.0 (GPL v2 from 2018 to 2020)
GPLv3-or-later (GPLv2-or-later before 6.3.0); MCL Apache 2.0
Licence changes
Commons Clause removed 2019; EE split from 2025
v2 to v3 in 2020
v2 to v3 in 2024
Steward
Meili SAS
The Typesense company
Manticore Software LTD
Commercial offer
Meilisearch Cloud; EE licence
Typesense Cloud
Support and consulting
Releases in 2026
52 (24 minor)
30.0, 30.1, 30.2, 29.1; 31.0 RCs
Seven GitHub round-ups, 17.5.1 to 29.9.0
Foundation
None
None
None
Architecture
Meilisearch
Typesense
Manticore Search
Language
Rust
C++
C++ with a PHP sidecar (Buddy)
Index storage
LMDB, memory-mapped on disk
Whole index in RAM; raw data in RocksDB
RT tables: RAM chunk, disk chunks, binlog; row-wise or columnar
Schema
Schemaless documents; per-index settings
Declared collection schema
Declared table schema (SQL)
Writes
Asynchronous task queue
Synchronous import API
Synchronous SQL, JSON or bulk
Interfaces
REST
REST
SQL (MySQL protocol), JSON HTTP, Elasticsearch-style writes
Search features
Meilisearch 1.55
Typesense 30.2
Manticore 29.9
Typo tolerance default
On: 0 typos up to 4 letters, 1 from 5, 2 from 9; numbers too
On: up to 2; 1 from 4 letters, 2 from 7; only if fewer than 1 result
Off; OPTION fuzzy=1, fuzziness 2 by default
Prefix (search-as-you-type)
Last word, by default
Last word, by default
word* wildcard or CALL AUTOCOMPLETE
Multi-word default
last: drop words from the end, count partial matches
All words; drop words only if nothing matched
SQL: all words; JSON match: any word
Facets
facets with counts
facet_by; sampling off by default
FACET or GROUP BY
Filters
SQL-like filter expressions
filter_by expressions
SQL WHERE
Geo
_geoRadius, _geoBoundingBox, geo sort
geopoint field, radius and polygon
GEODIST() and polygon functions
Vector and hybrid
Embedders, hybrid.semanticRatio
Auto-embedding, hybrid search
KNN, auto-embeddings, hybrid search
Multi-tenant search
Tenant tokens with embedded filters
Scoped search keys with embedded parameters
Table-level grants; no row filter
Operations
Meilisearch
Typesense
Manticore Search
High availability
Replication and sharding in EE only (v1.37+)
Raft cluster, three or more nodes
Galera replication; sharded tables
Backups
Snapshots (on disk in CE; S3 streaming in EE) and dumps
POST /operations/snapshot, restored as a data directory
manticore-backup, SQL BACKUP, mysqldump
Upgrades
Snapshot first, then --upgrade-db (since v1.51); not atomic; dumps as fallback, never to an older version
Rolling: followers first, leader last; index rebuilt from disk
Read breaking changes; new index formats cannot be opened by older versions
Restart cost
Memory-mapped; fast in the drill
Rebuilds RAM index; grows with data
Fast in the drill; binlog replay
Telemetry default
On (--no-analytics)
Not documented
On (telemetry = 0)
Security
Meilisearch
Typesense
Manticore Search
Authentication default
None in development; master key required in production
API key required at start
Off until auth = 1
Key model
Master key, scoped API keys, tenant tokens
Admin key, scoped keys with actions and collections, scoped search keys
Users, passwords, bearer tokens, grants per table
Default bind address
localhost:7700
0.0.0.0
127.0.0.1 in the package config
TLS
Built-in options
Certificate and key options
HTTPS listener; needs SSL build for auth
Outbound request controls
Non-global IPs blocked since v1.34.1
--proxy-disallowed-dest-cidrs
Not documented
Worked example for the Vadodara scenario
The Vadodara team (invented) re-ran the drill below with their own top 200 failed searches from the PostgreSQL logs.
Step 1. Classify real queries: names with typos, short words (“fan”, “led”), codes, sizes (“1.5 sq mm”, “32a”, “1200mm”) and brands. Each class failed differently in the drill, so each gets its own test.
Step 2. Decide counting before UI. With Meilisearch’s default last strategy, “condiut pipe” reported 1,501 hits because documents with only “conduit” were counted; with matchingStrategy: all it reported 477, like Typesense. Choose what the dealer should see and set it explicitly.
Step 3. Give codes their own rules. Codes like VI-10432 broke each engine differently: Meilisearch matched neighbouring codes through numeric typos, Typesense found nothing for “10432” because the hyphenated code was one token, and Manticore needed fuzzy off to stay exact. The fixes are small:
# Meilisearch: no typos on numbers, all words required for this search
curl -X PATCH "$MEILI/indexes/products/settings/typo-tolerance" \
-H "Authorization: Bearer $MEILI_ADMIN_KEY" -H 'Content-Type: application/json' \
-d '{"disableOnNumbers": true}'
# search body: {"q": "mcb 32a", "matchingStrategy": "all", "filter": "in_stock = true"}
# Typesense: split codes on the hyphen at collection creation time
# {"name": "products", "token_separators": ["-"], "fields": [ ... ]}
# search: q=10432&query_by=sku,name&num_typos=0 for code lookups
# Manticore: fuzzy only for name search, never for codes
# CREATE TABLE products (...) min_infix_len='2';
# SELECT * FROM products WHERE MATCH('@sku 10432');
# SELECT * FROM products WHERE MATCH('@name celing fan') OPTION fuzzy=1;
Step 4. Enforce dealer scope on the server: a Meilisearch tenant token with dealer_ids = 7, or a Typesense scoped key with filter_by: dealer_ids:=7. In both, a client filter for another dealer only narrowed the result. On Manticore the rule must live in the application or in separate tables, because a read grant covers every row.
Step 5. Plan rebuild and failure. PostgreSQL stays the source of truth and the index is a rebuildable copy (20,000 products took under two seconds on each engine in the drill); snapshots only make recovery faster. If semantic search comes later, the trade-offs in the vector search post apply, and all three engines can store vectors next to keywords.
Security and hygiene
On 19 October 2026 the GitHub repository security advisories API returned two published advisories for typesense/typesense and none for meilisearch/meilisearch or manticoresoftware/manticoresearch. CVE records were checked through cveawg.mitre.org and OSV.
- CVE-2026-47216 (Typesense; published 12 June 2026, 10:42 PM IST; GitHub CNA; CVSS 4.0 score 8.7; GHSA-fpx5-8c99-247j). A crafted request to
/multi_searchcould crash the server without authentication. Affected before 29.1, and 30.0 before 30.2. - CVE-2026-47225 (Typesense; same date; CVSS 4.0 score 6.0; GHSA-97x4-gm45-jpcw). With server-side caching and scoped search keys, cached results could be reused across keys with different restrictions. Same fixed versions. The 30.2 notes list the cache-key fix.
- CVE-2026-92796 (Manticore; published 17 September 2026, 2:02 AM IST; VulnCheck CNA; CVSS 4.0 score 8.7, CVSS 3.1 score 8.8). Permissions were checked only for the first statement in a multi-statement SQL request, so a read-only user could read credential tables and get password hashes usable to log in as an administrator. Affected 27.0.0 to before 28.4.4. The CISA ADP entry records a public proof of concept.
- Meilisearch published fixes in release notes rather than GitHub advisories: a dump import path traversal (fixed in v1.33.1, January 2026), an SSRF through webhooks, embedders and network settings for keys with write access to configuration (v1.34.1, which now blocks non-global IPs by default), another authenticated SSRF (v1.43.1, May 2026), and on 24 June 2026 v1.47.1 and v1.48.2 for CVE-2026-57824 (index-scoped API keys could reach global state) and CVE-2026-57823 (limited disclosure past tenant token rules). On 19 October 2026 the CVE API returned “record does not exist” for both IDs and OSV had no entry, so the release notes are the only record.
Habits that matter more than CVE counts:
- Never ship an admin or master key to a browser or app; ship search keys, tenant tokens or scoped keys from your backend, with short expiry.
- Bind to a private address on purpose. Typesense’s default
--api-addressis0.0.0.0. - On Manticore, turn on
auth = 1before the port is reachable from anything but the application host, and back upauth.jsonseparately (see the drill). - Decide telemetry on purpose: Meilisearch and Manticore send it by default.
- If untrusted users can configure webhooks, embedders or remote URLs, treat that as a privileged action; several 2026 Meilisearch fixes were in this area.
- Pin versions, verify checksums, and re-run your tenant tests after every upgrade.
Decision guide
Situation
Lean towards
Why
Small team, one node is acceptable, rebuild from the database in minutes
Meilisearch CE
Simplest operations, strong typo defaults, tenant tokens, MIT
Search must survive a node failure without a commercial licence
Typesense cluster or Manticore with replication
Meilisearch replication is Enterprise Edition only
Catalogue fits comfortably in RAM; you want predictable latency
Typesense
Whole index in memory by design; size RAM with its guide
Team thinks in SQL; you need joins, grouping and log-style queries too
Manticore Search
SQL over the MySQL protocol, columnar storage, Galera
Many tenants share one index and must not see each other
Meilisearch or Typesense
Server-enforced filters in tokens or scoped keys; Manticore grants are per table
Very large data that will not fit in RAM
Meilisearch EE, Manticore, or the Elasticsearch family
Typesense RAM sizing becomes the constraint
Licence must be permissive for redistribution
Meilisearch CE
MIT; the other two are GPL; avoid EE binaries in production without a contract
Vadodara (invented) pick. The team chose Typesense 30.2 as a three-node cluster: the whole catalogue needs well under a gigabyte of RAM, sales staff use search all day so one node failure must not stop orders, and scoped search keys enforce dealer agreements on the server. Codes go into a field with token_separators: ["-"] and are searched with num_typos=0. They pinned 30.2, will test 31.0 when it leaves release candidates, and kept a Meilisearch CE prototype as the fallback if a single node with fast rebuilds turns out to be enough.
Checklist
- Write the search promise in one sentence and get it signed.
- Export your top failed queries and classify them.
- Set matching and counting behaviour explicitly instead of relying on defaults.
- Turn off typo tolerance for codes and numbers where a near match is a wrong product.
- Enforce tenant scope on the server and test that a client filter cannot widen it.
- Check that facet counts match the results the user sees, with and without a query.
- Size memory from the engine’s own guide, especially for Typesense.
- Practise a restore from snapshot or backup into a fresh directory, including keys and users.
- Bind to private addresses, decide telemetry, and keep admin keys off the client.
- Pin versions and re-run the whole suite at every upgrade.
Common mistakes
- Treating “typo-tolerant” as one feature that every engine implements the same way.
- Comparing hit counts across engines without knowing that one counts partial matches.
- Letting typo tolerance touch product codes, so “10432” also returns “10433”.
- Assuming short words get typo tolerance.
- Turning on fuzzy search everywhere without checking false positives such as “led” matching “red”.
- Putting an admin key in a mobile app because “it is only search”.
- Using a table-level read grant as if it were row-level security.
- Choosing Meilisearch for high availability without noticing replication is Enterprise Edition.
- Undersizing RAM for Typesense, or forgetting that restart time grows with the index.
- Restoring a backup and finding out only then that users and permissions were not in it.
A drill I ran on 19 October 2026
Shared Linux VM (Debian 13, 8 vCPU, 15 GiB RAM, other workloads running), no Docker. Final runs between about 2:29 AM and 2:41 AM IST. One box and one small invented catalogue, so timings show what each step involves, not which engine is faster.
Setup:
- Meilisearch 1.55.0 Community Edition binary (
meilisearch-linux-amd64, SHA-256 matched the GitHub release digest),--env production, a master key,--no-analytics, bound to 127.0.0.1. - Typesense 30.2 server tarball from
dl.typesense.org(MD5 matched thetypesense-server.md5.txtinside it; I found no published SHA-256), bound to 127.0.0.1 with CORS off. - Manticore Search 29.9.0 bundle package from Manticore’s APT repository (SHA-256 matched the repository index), unpacked rather than installed, on 127.0.0.1. My first start ran with default telemetry for about four minutes before I set
telemetry = 0. - Client: Python 3.13.5 standard library over HTTP. The same 20,000 invented products (seven invented brands, eight categories, six warehouses, one to four dealers each) went into all three; the Manticore table had
min_infix_len='2'.
Indexing took 1.30 s on Meilisearch (until the task succeeded), 0.59 s on Typesense and 0.77 s on Manticore. Memory after indexing: about 113, 137 and 60 MiB RSS; data on disk 33 MB, 36 MB and 6.1 MB. Single runs on a shared box.
Typo and prefix queries. Manticore was run with and without OPTION fuzzy=1; Meilisearch and Typesense with defaults.
Query
Meilisearch
Typesense
Manticore fuzzy
Manticore plain
ceiling fan
959
959
959
959
celing fan
959
959
959
0
submersable pump
468
468
468
0
mltimeter
156
156
156
0
led bulp
4,730 (all LED items)
1,151
1,151
0
condiut pipe
1,501 (477 with all)
477
477
0
mcb 32a
686 (78 with all)
78
78
78
swich
6,666
6,666
1,887
0
fen
0
0
534 (conduit bends)
0
wier 1.5
0
495
978
0
subm
468
468
2,845
0
10432
16 (exact first, then 10433, 10402)
0
3
1
What the table shows:
- “swich” gave 6,666 on Meilisearch and Typesense because a typo-corrected prefix matched “switches” and “switchgear” in category names; Manticore matched only “switch”.
- “fen” and “wier” are short: no typo allowed on Meilisearch, one on Typesense, two on Manticore, whose answer for “fen” was conduit bends.
- Manticore splits “1.5” into
1and5(CALL KEYWORDS), so 2.5 sq mm wires matched too. - With
disableOnNumbers: true, Meilisearch returned one hit for “10432”; so did a Typesense collection withtoken_separators: ["-"].
Relevance. Top results were sensible whenever an engine found anything, but the order differed: on tied scores, Meilisearch and Manticore returned the lowest ids first (8, 31, 72) and Typesense the highest (19990, 19983, 19976), so set an explicit tie-breaker sort. “ceiling fan white 1200” found nothing on Manticore, because 1200 is not the token 1200mm; the other two treated the last word as a prefix. “copper wire 2.5 frls” returned 159 on Manticore without fuzzy and 0 with it, in repeated runs. I did not dig further.
Facets and filters. With the same hit set, all three agreed exactly: in-stock category counts (Lighting 3,731, Switches and sockets 3,040, Switchgear 2,318, Wires and cables 2,281, Conduits and fittings 1,595, Fans 1,585, Tools 749, Pumps 718); fans priced Rs 500 to 3,000 in stock, 629; brand = 'vidyut' in lower case, 2,888, the same as ‘Vidyut’; dealer 7 in an array field, 1,268; within 60 km of Vadodara, 6,728; and category = 'Fan', 0 everywhere, since filters have no typo tolerance. With a query, facets followed matching: “led” gave Lighting 4,730 on two engines, while Manticore fuzzy added 571 wires (it matched “red”).
Tenant scope.
Check
Meilisearch tenant token
Typesense scoped key
Manticore read grant
Rows visible to dealer 7
1,268
1,268
20,000 (no row rule)
Client asks for dealer 8
64 (intersection only)
64 (intersection only)
Not applicable
Read raw documents or list keys
403
401
Users list and writes denied
Tampered token or key
403
401
Wrong password 401
With use_cache=true, alternating scoped keys for dealers 7 and 8 kept returning 1,268 and 1,247 on 30.2, the case behind CVE-2026-47225.
Restart and restore. After a restart, documents were back in 0.12 s on Meilisearch, 3.06 s on Typesense (rebuilding the RAM index) and 0.23 s on Manticore, and all three still refused unauthenticated requests. A Meilisearch snapshot took 1.22 s (11.0 MB file); a second instance started with --import-snapshot in 0.2 s, returned the same top ids and accepted the old search key. A Typesense snapshot returned in 0.02 s; a second node started on a copy of it in 6.43 s with the same results and the two keys that existed at snapshot time. Manticore’s manticore-backup took 0.09 s for the table. The restore was where I learnt the most:
# manticore-backup --restore refused while the daemon ran ("Destination file already exists"),
# then because the config file existed, then because the data dir was missing.
# What worked: stop searchd, move the config away, leave an EMPTY data_dir, then restore.
manticore-backup --config=manticore.conf.keep --backup-dir=/backup --restore=backup-20261018210944
# Restored: 20,000 rows, identical fuzzy results. Not restored: auth.json.
# With auth = 1 and no users, every login failed, including admin, until:
printf 'admin\n%s\n%s\n' "$PW" "$PW" | searchd --config manticore.conf --auth-non-interactive
Neither a table backup nor a full backup contained auth.json, so the dealer user had to be recreated. Practise restores with security in them, not only data.
What this box could not test: clusters and failover, large data or concurrency, Hindi or Gujarati text, vector and hybrid search, upgrades, Meilisearch EE and Typesense 31.0 candidates. All three servers were stopped by 2:41 AM IST. Scripts, logs and results are under drill47/.
Unlearn
- Unlearn “typo-tolerant” as a checkbox.
- Unlearn that a result count means the same thing in every engine.
- Unlearn that a fuzzier search is a better search.
- Unlearn that an open-source licence on the repository covers every binary on the release page.
- Unlearn trusting a restore that brings back data but not users.
Re-learn
- Re-learn your dealers’ real queries, not the demo queries.
- Re-learn the three layers: matching rules, counting rules, operating rules.
- Re-learn tokenisation for codes, sizes and decimals.
- Re-learn where your index lives: RAM, memory-mapped disk, or chunks and binlogs.
- Re-learn the licence of each feature you plan to use, release by release.
Closing
Self-hosted search in 2026 is less about raw speed and more about rules you can explain to a user. Meilisearch 1.55 is the easiest to run and the most forgiving with typos, with an MIT core and an Enterprise Edition that now owns replication and sharding. Typesense 30.2 keeps everything in RAM, ships Raft clustering and scoped keys in its GPL server, and is waiting on 31.0. Manticore Search 29.9 brings SQL, Galera and a Sphinx lineage, with opt-in authentication and fuzzy search that needs careful tuning. Learn the three layers. Unlearn “typo-tolerant” as a feature name. Re-learn your own queries and codes. Practise a restore with keys and users in it. Apply it before you add another search box.
Sources
Meilisearch
- meilisearch/meilisearch on GitHub
- Meilisearch v1.55.0 release
- Meilisearch v1.19.0 release (sharding, first EE feature)
- Meilisearch v1.28.0 release (separate CE and EE binaries)
- Meilisearch v1.31.0 release (S3-streaming snapshots move to EE)
- Meilisearch v1.37.0 release (replicated sharding)
- Meilisearch LICENSE
- Meilisearch LICENSE-EE (BUSL 1.1, adapted)
- Meilisearch commit: change the licence to MIT (2019)
- Enterprise and Community editions
- Replication and sharding
- Typo tolerance settings
- Matching strategy
- Known limitations
- Storage (LMDB)
- Snapshots
- Dumps
- Updating Meilisearch
- Security and tenant tokens
- Generate a tenant token from scratch
- Hybrid search
- Geo search
- Telemetry
Typesense
- typesense/typesense on GitHub
- Typesense v30.2 release
- Typesense v30.0 release
- Typesense v26.0 release (new versioning scheme)
- Typesense LICENSE.txt (GPL-3.0)
- Typesense commit: licence text updated to GPL v3 (2020)
- Typesense Docker Hub tags (31.0 release candidates)
- High availability
- System requirements and RAM sizing
- Updating Typesense
- Search parameters (typos, prefix, thresholds, facets)
- Collections (schema, token separators)
- API keys and scoped search keys
- Cluster operations (snapshots)
- Server configuration
- Geosearch
- Vector and hybrid search
Manticore Search
- manticoresoftware/manticoresearch on GitHub
- Manticore Search 29.9.0 release
- Manticore Search 28.4.4 release
- Manticore Search 27.1.5 release (authentication, sharded tables)
- Manticore Search 25.0.0 release (bundle package, breaking changes)
- Licence change to GPLv3-or-later (PR 1720)
- Manticore LICENSE
- Sphinx on GitHub
- Manticore Columnar Library
- manticore-backup
- Installation
- Full-text matching basics (SQL and JSON defaults)
- Spell correction and fuzzy search
- Faceted search
- Geo search
- KNN vector search
- Hybrid search
- Real-time tables
- Setting up replication
- Sharded tables
- Backup and restore
- Authentication and authorisation
- Telemetry
Security records
- CVE-2026-47216 on cve.org
- GHSA-fpx5-8c99-247j (Typesense)
- CVE-2026-47225 on cve.org
- GHSA-97x4-gm45-jpcw (Typesense)
- CVE-2026-92796 on cve.org
- VulnCheck advisory for CVE-2026-92796
- Meilisearch v1.33.1 (dump import path traversal)
- Meilisearch v1.34.1 (SSRF fix, non-global IPs blocked)
- Meilisearch v1.43.1 (authenticated SSRF fix)
- Meilisearch v1.48.2 (CVE-2026-57823 and CVE-2026-57824)
Internal
Releted Posts
Log storage in 2026: revisit Grafana Loki, VictoriaLogs and OpenObserve before you keep another month of logs
Picture a platform team in Pune that runs a B2B lending stack for NBFCs across Maharashtra and Gujarat (an invented example, not a real client).
Read moreSchema migrations in 2026: revisit Atlas, Flyway and Liquibase before you ship another ALTER
Picture a retail SaaS company in Coimbatore that runs order management for textile wholesalers across Tamil Nadu (an invented example, not a real client).
Read moreChange data capture in 2026: revisit Debezium, Apache Flink CDC and PeerDB before you stream another table
Picture a SaaS company in Pune that runs billing for FMCG distributors across Maharashtra (an invented example, not a real client).
Read more