Lower max total hits
- Lower max total hits
- Lower max total hits
- Configure granular filterable attributes
- Reduce proximity precision
- Lower max values per facet
- Limit searchable attributes
- Configure stop words
- Tune typo tolerance
- Disable prefix search
- Use search cutoff as a safety net
- Debug with performance details
- Next steps
- Debug search performance
- Optimize indexing
- Ranking pipeline
- Granular filters
As your dataset grows, search performance depends on how you configure index settings and search parameters. This page covers practical strategies for keeping search fast, ordered from highest to lowest impact.
This page focuses on search-time performance. For indexing performance, see optimize batch performance.
Lower max total hits
Impact: very high
The maxTotalHits pagination setting controls how deep Meilisearch ranks results using the bucket sort pipeline. By default, Meilisearch ranks up to 1,000 documents per query.
Some users set this to very high values (100K or even 1M), forcing Meilisearch to run the full ranking pipeline across all matching documents for every single query. This is almost never necessary because users rarely go beyond the first few pages of results.
curl \
-X PATCH 'MEILISEARCH_URL/indexes/products/settings/pagination' \
-H 'Content-Type: application/json' \
--data-binary '{
"maxTotalHits": 200
}'
Set maxTotalHits to the realistic maximum a user would ever paginate to. For most applications, 100 to 200 is plenty (that covers 5 to 10 pages of 20 results). Going higher means Meilisearch spends time ranking documents nobody will ever see.
Configure granular filterable attributes
Impact: very high
Every attribute listed in filterableAttributes creates additional data structures during indexing that are also evaluated at search time. The more filter features you enable, the more work Meilisearch does.
Use granular filterable attributes to enable only the filter operations you actually need per attribute:
curl \
-X PATCH 'MEILISEARCH_URL/indexes/products/settings' \
-H 'Content-Type: application/json' \
--data-binary '{
"filterableAttributes": [
{
"attributePatterns": ["category", "brand"],
"features": {
"facetSearch": false,
"filter": { "equality": true, "comparison": false }
}
},
{
"attributePatterns": ["price"],
"features": {
"facetSearch": false,
"filter": { "equality": false, "comparison": true }
}
}
]
}'
Key things to disable if you don’t need them:
facetSearch: facet search is resource-intensive. Disable it on attributes where users will never search within facet valuescomparison: comparison filters (<,>,TO) require additional data structures. Only enable on numeric/date fields that actually need range filtering
Reduce proximity precision
Impact: very high
The proximity ranking rule measures the distance between matched query terms in a document. By default, Meilisearch calculates this at word-level precision, which means it tracks the exact position of every word in every document. This is one of the most expensive operations in the search pipeline, both at indexing time and at search time.
Switching to attribute-level precision drastically reduces this cost:
curl \
-X PUT 'MEILISEARCH_URL/indexes/products/settings/proximity-precision' \
-H 'Content-Type: application/json' \
--data-binary '"byAttribute"'
With byAttribute, Meilisearch only checks whether query terms appear in the same attribute, not their exact distance within it. This makes indexing significantly faster and reduces the work done during each search.
Calculating the distance between words is a resource-intensive operation. Lowering the precision of this operation may significantly improve performance and will have little impact on result relevancy in most use cases.
The trade-off is that multi-word queries like “dark knight” will rank documents the same whether the words are adjacent or far apart within the same field. For most use cases (ecommerce, documentation, catalogs), this difference is negligible. Word-level precision matters most for long-form content where word proximity is a strong relevancy signal.
Lower max values per facet
Impact: high
The maxValuesPerFacet setting (default: 100) controls how many distinct facet values Meilisearch returns in the facetDistribution. If you have attributes with thousands of unique values (like tags or cities), Meilisearch computes counts for all of them up to this limit.
curl \
-X PATCH 'MEILISEARCH_URL/indexes/products/settings/faceting' \
-H 'Content-Type: application/json' \
--data-binary '{
"maxValuesPerFacet": 20
}'
Set this to the number of facet values you actually display in your UI. If your sidebar shows 10 categories, there is no reason to compute counts for 100.
Limit searchable attributes
Impact: high By default, Meilisearch searches through every field in your documents. Restrict searchable attributes to only the fields that matter for search:
curl \
-X PUT 'MEILISEARCH_URL/indexes/products/settings/searchable-attributes' \
-H 'Content-Type: application/json' \
--data-binary '["name", "description", "category"]'
Exclude fields like IDs, URLs, timestamps, and numeric values that users would never search by text. This reduces the amount of data Meilisearch processes during each query.
Configure stop words
Impact: medium Stop words like “the”, “is”, and “of” appear in nearly every document and slow down query processing without improving result quality:
curl \
-X PUT 'MEILISEARCH_URL/indexes/products/settings/stop-words' \
-H 'Content-Type: application/json' \
--data-binary '["the", "a", "an", "is", "are", "of", "in", "to", "and", "or"]'
This reduces the number of terms Meilisearch evaluates during each search.
Tune typo tolerance
Impact: medium Typo tolerance expands the search space for each query term. On large datasets, you can reduce this cost: Disable typos on numbers: prevents false positives like “2024” matching “2025” and reduces the search space for numeric terms:
curl \
-X PATCH 'MEILISEARCH_URL/indexes/products/settings/typo-tolerance' \
-H 'Content-Type: application/json' \
--data-binary '{
"disableOnNumbers": true
}'
Increase minimum word size for typos: by default, 1 typo is allowed on words of 5+ chars and 2 typos on 9+ chars. Raising these thresholds reduces the fuzzy matching work:
curl \
-X PATCH 'MEILISEARCH_URL/indexes/products/settings/typo-tolerance' \
-H 'Content-Type: application/json' \
--data-binary '{
"minWordSizeForTypos": {
"oneTypo": 6,
"twoTypos": 12
}
}'
Disable typos on structured fields like SKUs or product codes where typos are unlikely:
curl \
-X PATCH 'MEILISEARCH_URL/indexes/products/settings/typo-tolerance' \
-H 'Content-Type: application/json' \
--data-binary '{
"disableOnAttributes": ["sku", "product_code"]
}'
Disable prefix search
Impact: medium Prefix search enables “search as you type” but increases index size. If your application uses form-based search (users type a full query and press Enter), disable it:
curl \
-X PUT 'MEILISEARCH_URL/indexes/products/settings/prefix-search' \
-H 'Content-Type: application/json' \
--data-binary '"disabled"'
Use search cutoff as a safety net
Impact: low (safety measure) Set a search cutoff to guarantee a maximum response time. This is not a performance optimization per se, but a safety net against unusually long queries or potential abuse:
curl \
-X PUT 'MEILISEARCH_URL/indexes/products/settings/search-cutoff-ms' \
-H 'Content-Type: application/json' \
--data-binary '500'
Don’t go below 500ms. If your searches are consistently slow, fix the root cause with the optimizations above.
Debug with performance details
If you need to identify exactly which stage of the search pipeline is slow, use the showPerformanceDetails parameter. It returns per-stage timing information so you can target your optimizations precisely.
See debug search performance for full instructions.
Next steps
Debug search performance
Use showPerformanceDetails to pinpoint bottlenecks
Optimize indexing
Speed up document indexing and batch operations
Ranking pipeline
Understand how bucket sort ranks results
Granular filters
Fine-tune which filter operations are enabled per attribute
