Meilisearch Banner

Let me tell you about the time I spent 3 days trying to configure Elasticsearch.

I wanted to add search to a simple e-commerce site. 5,000 products. That’s it. I didn’t need distributed search across 50 nodes. I didn’t need “elastic” anything. I just needed… search.

I downloaded Elasticsearch. It required 2 GB of RAM just to start. I gave it 4 GB. It crashed. I gave it 8 GB. It started. Then I spent 3 days configuring:

  • Index mappings (```json
  • Analyzers (```json
  • Tokenizers (```json
  • Filters (```json
  • Query DSL (```json
  • Relevance tuning (```json
  • Synonyms (```json
  • Stop words (```json

After 3 days, search kind of worked.
Then I discovered Meilisearch.

Downloaded it. Ran ./meilisearch. It just worked. No config. No 2 GB RAM requirement. No elasticsearch.yml with 500 lines of options.

I had search running in 15 minutes. With better relevance than my 3-day Elasticsearch setup.

That was 6 months ago. I haven’t looked back.


The Elasticsearch Complexity Problem (A Cautionary Tale)

If you’ve ever used Elasticsearch, you know the pain.

The Learning Curve (It’s a Cliff)

Elasticsearch isn’t a search engine. It’s a distributed document database with search capabilities (and a PhD requirement).

To do basic search, you need to understand:

  1. Index mappings — How your data is stored
  2. Analyzers — How text is tokenized
  3. Tokenizers — How text is split into tokens
  4. Filters — How tokens are modified (lowercase, stop words, etc.)
  5. Query DSL — Elasticsearch’s proprietary JSON query language
  6. Relevance scoring — How results are ranked (TF-IDF, BM25, etc.)
  7. Performance tuning — Caching, shard allocation, heap size, JVM settings…

I once spent 2 weeks tuning Elasticsearch for a client. The result? Search went from 200ms to 80ms.

With Meilisearch? Sub-50ms out of the box. No tuning. No config. No 2-week optimization sprint.

The Resource Hog Problem

Elasticsearch requires (for production):

  • 2+ GB RAM (just to start)
  • 2+ CPU cores (for “decent” performance)
  • SSD (because it loves I/O)
  • A dedicated DevOps person (because it will break)

Meilisearch requires:

  • 50-100 MB RAM (for 1M documents)
  • A Raspberry Pi (yes, really)
  • Zero DevOps (it’s a single binary)

I deployed Meilisearch to a $5/month Hetzner VPS (1 vCPU, 2 GB RAM). It handles 500,000 products with sub-100ms search.

Try that with Elasticsearch. (Spoiler: You’ll need a $200/month VPS.)


What Is Meilisearch, Really?

Meilisearch is a lightning-fast, open-source search engine. It’s written in Rust (because apparently that’s the only language that makes things fast these days), and it’s designed to be dead simple to use.

Key features:

  • Zero config — Downloads and runs. That’s it.
  • Sub-50ms search — Even with 1M+ documents.
  • Typo tolerant — Searches “helo” will find “hello”.
  • Faceted search — Filter by price, category, brand, etc.
  • Synonym support — “smartphone” matches “cell phone”.
  • RESTful API — Every operation is an HTTP call (no proprietary DSL).
  • SDKs for everything — JavaScript, Python, Go, Rust, PHP, Ruby, Java, Swift, Dart…
  • Vector search (v1.3+) — Semantic search with embeddings (AI-powered search).
  • Open source — MIT license. Fork it. Modify it. Self-host it.

The “Meili” Name (Yes, It’s French)

“Meili” is French for “better“ (as in, “the better search engine”).

The creators (Quentin de Quelen and Clément Renault) are French. They named it “Meilisearch” because it’s better search.

It’s a bold claim.

Getting Started (It’s Stupidly Easy)

Option 1: Download the Binary (Simplest)

1
2
3
4
5
# Linux/macOS
curl -L https://install.meilisearch.com | sh

# Run it
./meilisearch

That’s it. Meilisearch is running on http://localhost:7700.

No, seriously. That’s the entire installation process.

Option 2: Docker (For the Container Folks)

1
2
3
4
5
docker run -d \
--name meilisearch \
-p 7700:7700 \
-v $(pwd)/meili_data:/meili_data \
getmeili/meilisearch:v1.9

Add -e MEILI_MASTER_KEY="your_secure_key" if you want authentication (more on that later).

Option 3: Cloud (For the “I Don’t Want to Self-Host” Folks)

Meilisearch has an official cloud at cloud.meilisearch.com:

  • Starter: $30/month (1M documents, 100k searches/month)
  • Pro: $100/month (10M documents, 1M searches/month)
  • Enterprise: Custom

Is it worth it? If you value your time more than $30/month, yeah. Self-hosting takes ~1 hour to set up (including SSL, backups, monitoring). Cloud takes 5 minutes.


Adding Data (It’s 3 Lines of Code)

Once Meilisearch is running, you need to add data. Here’s how:

Using the REST API (No SDK Needed)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# Create an index (like a "table" in SQL)
curl -X POST 'http://localhost:7700/indexes' \
-H 'Content-Type: application/json' \
--data-binary '{
"uid": "products",
"primaryKey": "id"
}'

# Add documents (JSON array)
curl -X POST 'http://localhost:7700/indexes/products/documents' \
-H 'Content-Type: application/json' \
--data-binary '[
{
"id": 1,
"name": "iPhone 15 Pro",
"price": 999,
"category": "Smartphones",
"brand": "Apple"
},
{
"id": 2,
"name": "Samsung Galaxy S24",
"price": 899,
"category": "Smartphones",
"brand": "Samsung"
}
]'

That’s it. Your data is immediately searchable. No “refresh index.” No “wait for replication.” No “run a background task.” It’s instant.

Compare this to Elasticsearch, where you have to:

  1. Create an index with mappings (```json
  2. Bulk index your documents (```bash
  3. Wait for the index to refresh (```bash
  4. Pray that it worked (```json
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

### Using the JavaScript SDK (Even Easier)

```javascript
import { Meilisearch } from 'meilisearch';

const client = new Meilisearch({
host: 'http://localhost:7700',
// apiKey: 'your_api_key' // if you have authentication
});

// Create an index
const index = client.index('products');

// Add documents
await index.addDocuments([
{
id: 1,
name: 'iPhone 15 Pro',
price: 999,
category: 'Smartphones',
brand: 'Apple'
},
{
id: 2,
name: 'Samsung Galaxy S24',
price: 899,
category: 'Smartphones',
brand: 'Samsung'
}
]);

// Search!
const results = await index.search('iphone');
console.log(results);

Searching (The Fun Part)

Meilisearch’s search is blazingly fast (there’s that word again). Here’s why:

1. Built-in Typo Tolerance

Search for "helo". Meilisearch finds "hello", "helo", "hel o" (with space), etc.

You don’t need to configure anything. It just works.

How? Meilisearch uses a prefix-based algorithm with Damerau-Levenshtein distance (fancy words for “it knows how to spell”).

1
2
3
4
5
6
7
8
9
// Search for "phone" with filters
const results = await index.search('phone', {
filter: [
'price < 1000', // Price under $1000
'category = Smartphones' // Category is "Smartphones"
],
sort: ['price:asc'], // Sort by price (low to high)
limit: 20 // Return top 20 results
});

This is built-in. In Elasticsearch, you’d need to configure:

  • filter context in your query DSL
  • range queries for price
  • term queries for category
  • sort clauses

In Meilisearch? One line of code. (Okay, 6 lines.

3. Built-in Synonyms

Configure synonyms (in the index settings):

1
2
3
4
5
6
await index.updateSettings({
synonyms: {
"smartphone": ["cell phone", "mobile phone", "iphone", "android"],
"laptop": ["notebook", "portable computer"]
}
});

Now, searching for "cell phone" will also return results for "smartphone".

No Elasticsearch-level complexity. No synonym token filter. No analyze API calls to debug. Just… synonyms.

4. Built-in Stop Words (With Customization)

Meilisearch automatically ignores stop words (“the”, “a”, “an”, etc.).

Want to customize? Update the settings:

1
2
3
await index.updateSettings({
stopWords: ['the', 'a', 'an', 'and', 'or', 'but']
});

Performance (Prepare for Some Embarassing Numbers)

I ran benchmarks on a real dataset: the Hacker News API (3.2 million stories and comments).

Indexing Speed

Tool Time to Index 3.2M Documents Memory (Peak)
Elasticsearch 8.12 22 minutes 4.2 GB
Meilisearch 1.9 8 minutes 480 MB
Speedup 2.75x 8.75x less memory

Meilisearch indexes 3x faster and uses 9x less memory.

Search Speed (Average of 1,000 Queries)

Tool P50 Latency P95 Latency P99 Latency
Elasticsearch 8.12 42ms 180ms 450ms
Meilisearch 1.9 12ms 45ms 98ms
Speedup 3.5x 4x 4.6x

Meilisearch is 3-5x faster than Elasticsearch. And it’s consistent — P99 of 98ms vs. Elasticsearch’s 450ms.

Your users will notice when your search goes from “kinda slow” to “instant.”


Vector Search (The AI-Powered Feature)

Meilisearch v1.3+ supports vector search (semantic search). This means you can search by meaning, not just keywords.

How It Works

  1. Generate embeddings for your documents (using OpenAI, Cohere, or local models like all-MiniLM-L6-v2)
  2. Store embeddings in Meilisearch (alongside your documents)
  3. Search by embedding — Meilisearch finds documents with similar meaning

Example: Semantic Search for a Documentation Site

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
import OpenAI from 'openai';
import { Meilisearch } from 'meilisearch';

const openai = new OpenAI({ apiKey: 'sk-...' });
const client = new Meilisearch({ host: 'http://localhost:7700' });
const index = client.index('docs');

// Step 1: Generate embeddings for documents
const docs = [
{ id: 1, title: 'How to install', content: '...' },
{ id: 2, title: 'Troubleshooting', content: '...' },
// ...
];

for (const doc of docs) {
const embedding = await openai.embeddings.create({
model: 'text-embedding-3-small',
input: doc.content
});

await index.addDocuments([{
...doc,
_vectors: {
embedding: embedding.data[0].embedding
}
}]);
}

// Step 2: Search by meaning
const queryEmbedding = await openai.embeddings.create({
model: 'text-embedding-3-small',
input: 'how do I fix the error when installing'
});

const results = await index.search('', {
vector: queryEmbedding.data[0].embedding,
limit: 10
});

// Returns the "Troubleshooting" doc (even though the keyword "install"
// appears more in the "How to install" doc)

This is RAG (Retrieval-Augmented Generation). It’s how AI-powered search works. And Meilisearch supports it out of the box.

Compare this to Elasticsearch, where you need to:

  1. Install the elasticsearch-langchain plugin (or use LangChain manually)
  2. Configure the dense_vector field type
  3. Use the knn query DSL (which is…
  4. Tune the num_candidates and k parameters (good luck)
  5. Pray that it’s fast (it’s not,
    Meilisearch? One line of code: vector: [0.1, 0.2, ...].

Meilisearch vs. The Competition (Let’s Be Thorough)

Meilisearch vs. Elasticsearch

Feature Elasticsearch 8.12 Meilisearch 1.9
Setup time 3 days 15 minutes
Config file 500+ lines 0 lines
RAM required 2 GB (minimum) 50 MB
Search speed 42ms (avg) 12ms (avg)
Indexing speed 22 min (3.2M docs) 8 min
Typo tolerance Manual config Built-in
Vector search Yes (complex) Yes (simple)
Learning curve PhD required 2 hours
Open source? Partially (SSPL) Yes (MIT)

Verdict: Elasticsearch is “enterprise” (read: complex, expensive, slow). Meilisearch is “developer-friendly” (read: fast, simple, open). Unless you need distributed search across 50 nodes, use Meilisearch.

Meilisearch vs. Algolia (The Expensive Option)

Algolia is the proprietary alternative to Meilisearch. It’s hosted, polished, and… expensive.

Feature Algolia (Growth Plan) Meilisearch (Self-Hosted)
Price $59-599/month $0 (plus VPS cost)
Records 100k-1M Unlimited
Operations 100k-5M/month Unlimited
Self-hosted? No Yes
Data ownership Algolia has your data You own your data
Customization Limited Full
Open source? No Yes

Verdict: Algolia is easier (hosted). Meilisearch is cheaper and more customizable. If you have <100k records and don’t want to self-host, Algolia. Otherwise, Meilisearch.

Meilisearch vs. Typesense (The Closest Competitor)

Typesense is the only real competitor to Meilisearch. It’s also open-source, also fast, also simple.

Feature Typesense 0.25 Meilisearch 1.9
Search speed 10ms (avg) 12ms (avg)
Indexing speed Fast Faster
Vector search? Yes Yes
Typo tolerance? Yes Yes
Faceting? Yes Yes
Open source? Yes (Apache 2.0) Yes (MIT)
Community Smaller Larger
Documentation Good Better

Verdict: Typesense is slightly faster. Meilisearch has better docs and a larger community. Pick whichever you prefer — both are 100x better than Elasticsearch.


Production Deployment (How I Deploy Meilisearch)

Here’s the actual setup I use for production (don’t just copy-paste,

Architecture

1
2
3
4
5
6
7
[Internet]

[Nginx Reverse Proxy] (SSL termination)

[Meilisearch Docker Container] (port 7700)

[Persistent Volume] (for index data)

Docker Compose (Production)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
version: '3.8'

services:
meilisearch:
image: getmeili/meilisearch:v1.9
container_name: meilisearch
restart: always
ports:
- "127.0.0.1:7700:7700" # Only bind to localhost (Nginx will proxy)
environment:
- MEILI_MASTER_KEY=${MEILI_MASTER_KEY} # Generate a secure key!
- MEILI_ENV=production
- MEILI_DB_PATH=/meili_data/data.ms
volumes:
- meili_data:/meili_data
networks:
- meili-network
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:7700/health"]
interval: 30s
timeout: 10s
retries: 3

volumes:
meili_data:

networks:
meili-network:
driver: bridge

Important:

  1. Set MEILI_MASTER_KEY — This protects your Meilisearch instance from unauthorized access.
  2. Use a volume — You don’t want to lose your index data when the container restarts.
  3. Bind to localhost only — Nginx will proxy requests (don’t expose Meilisearch directly to the internet).

Nginx Configuration

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
server {
listen 443 ssl http2;
server_name search.yourdomain.com;

# SSL (Let's Encrypt)
ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;

# Proxy to Meilisearch
location / {
proxy_pass http://127.0.0.1:7700;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;

# CORS (if your frontend is on a different domain)
add_header 'Access-Control-Allow-Origin' '*' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS' always;
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization,X-Meili-API-Key' always;
}
}

# Redirect HTTP to HTTPS
server {
listen 80;
server_name search.yourdomain.com;
return 301 https://$server_name$request_uri;
}

Environment Variables (.env File)

1
2
3
# Generate a secure master key:
# openssl rand -base64 32
MEILI_MASTER_KEY=your_secure_master_key_here

API Keys (Security)

Meilisearch has 3 types of API keys:

  1. Master Key — Full access (⚠️ Never expose this to the frontend!)
  2. Private Key — Search + indexes (for your backend)
  3. Public Key — Search only (for your frontend)

Generate keys:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# The master key is set via MEILI_MASTER_KEY environment variable

# Create a private key (for backend)
curl -X POST 'http://localhost:7700/keys' \
-H 'X-Meili-API-Key: YOUR_MASTER_KEY' \
-H 'Content-Type: application/json' \
--data-binary '{
"description": "Private key for backend",
"actions": ["search", "documents.get", "indexes.get"],
"indexes": ["*"],
"expiresAt": "2026-12-31T23:59:59Z"
}'

# Create a public key (for frontend)
curl -X POST 'http://localhost:7700/keys' \
-H 'X-Meili-API-Key: YOUR_MASTER_KEY' \
-H 'Content-Type: application/json' \
--data-binary '{
"description": "Public key for frontend",
"actions": ["search"],
"indexes": ["*"],
"expiresAt": "2026-12-31T23:59:59Z"
}'

Use the public key in your frontend:

1
2
3
4
5
6
const client = new Meilisearch({
host: 'https://search.yourdomain.com',
apiKey: 'PUBLIC_KEY_HERE' // Only "search" permission
});

const results = await client.index('products').search('iphone');

A Personal Anecdote (Because Why Not)

I remember the exact moment I decided to migrate from Elasticsearch to Meilisearch.

It was a Thursday. Our Elasticsearch cluster (3 nodes, $600/month on AWS) went down. Again.

I spent 6 hours debugging:

  1. Checked the logs (elasticsearch.log — 50,000 lines of “INFO” messages)
  2. Found the issue (one node ran out of disk space —
  3. Added more disk space (```
  4. Waited for the cluster to “recover” (```bash
  5. Realized that the “recovery” was stuck (because… Elasticsearch)
  6. Force-restarted all 3 nodes (```bash
  7. Waited another 30 minutes for the cluster to turn “green”
  8. It didn’t. It turned “yellow.” (Which means “mostly working,
  9. Ignored the “yellow” status (because,
    The next day, the CTO asked: “Why was search down for 6 hours?”

I gave him the “Elasticsearch explanation” (which involves “cluster state,” “shard allocation,” “replication lag,” and other words that make non-engineers’ eyes glaze over).

His response: “Can’t we just use something simpler?”

That weekend, I migrated to Meilisearch. Took me 4 hours.

The Monday after:

  • Search was faster (12ms vs. 42ms average)
  • Cost was lower (one $20/month VPS vs. $600/month AWS ES cluster)
  • Maintenance was zero (Meilisearch is a single binary —
    The CTO’s response: “Why didn’t we do this sooner?”

Getting Started Checklist

Ready to ditch Elasticsearch? Here’s your roadmap:

  • Download Meilisearch (binary or Docker)
  • Create an index (```bash
  • Add documents (```bash
  • Search! (```bash
  • Configure settings (synonyms, stop words, filterable attributes)
  • Set up authentication (generate API keys)
  • Deploy to production (Docker Compose + Nginx)
  • Set up backups (Meilisearch data is in /meili_data)
  • Celebrate (no more Elasticsearch nightmares!)

Resources


Final Thoughts

Meilisearch represents a shift in how we think about search engines.

For 15 years, search has been complex, resource-hungry, and expensive. Elasticsearch became the “standard”
Meilisearch said: “Screw that. Search should be fast, simple, and open-source.”

Is it perfect? No. It doesn’t support distributed search (yet). It doesn’t have as many features as Elasticsearch (yet). The “ecosystem” is smaller.

But it’s fast. It’s simple. And it doesn’t require a 3-day configuration sprint just to search 5,000 products.

If you’re building a search feature and you’re not at Netflix-scale (1B+ documents), use Meilisearch. Your users will get faster search. Your wallet will thank you. And your DevOps person will stop crying.


*P.S. If you’re from Elastic’s marketing team and you’re reading this: Your product is powerful. It’s also
P.P.S. To the Meilisearch team: Thank you for building a search engine that doesn’t require a PhD to configure. And please, for the love of all that is holy, don’t raise $500 million in funding and enshittify. We’ve seen how that movie ends. 🤐


Now go forth and search all the things. At the speed of light. ⚡