Skip to main content
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 values
  • comparison: 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. 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"]
  }'
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