> ## Documentation Index
> Fetch the complete documentation index at: https://www.meilisearch.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Performing personalized search queries

> Search personalization uses context about the person performing the search to provide results more relevant to that specific user. This article guides you through configuring and performing personalized search queries.

## Generating a user profile

Search personalization requires a profile of the user performing the search. Meilisearch does not yet provide automated generation of user profiles.

You'll need to **dynamically generate a user profile** for each search request. This should summarize relevant traits, such as:

* Category preferences, like brand or size
* Price sensitivity, like budget-conscious
* Possible use cases, such as fitness and sport
* Other assorted information, such as general interests or location

The re-ranking model only processes positive signals. It cannot interpret negative statements like "dislikes blue" or "is not interested in luxury brands". Always use affirmatively stated preferences instead: "likes the color red", "prefers cheaper brands".

## Perform a personalized search

Once search personalization is active and you have a pipeline in place to generate user profiles, you are ready to perform personalized searches.

Submit a search query and include the `personalize` search parameter. `personalize` must be an object with a single field, `userContext`. Use the profile you generated in the previous step as the value for `userContext`:

<CodeGroup>
  ```bash cURL theme={null}
  curl \
    -X POST 'MEILISEARCH_URL/indexes/INDEX_NAME/search' \
    -H 'Content-Type: application/json' \
    --data-binary '{
      "q": "wireless keyboard",
      "personalize": {
        "userContext": "The user prefers compact mechanical keyboards from Keychron or Logitech, with a mid-range budget and quiet keys for remote work."
      }
    }'
  ```
</CodeGroup>

## Reranking scope and the `limit` parameter

The reranker only sees the documents that Meilisearch returns for a given query. This means `limit` directly controls how many documents the reranker can choose from.

If you set `limit` to 20, the reranker picks the best order from those 20 documents. It cannot promote a document that Meilisearch did not return. Increasing `limit` gives the reranker a wider pool to work with, but also increases latency and the number of tokens sent to the reranking model.

A `limit` between 20 and 100 is a reasonable starting point for most personalized search use cases. Go higher if ranking quality matters more than latency for your application.

## Limits

Personalized search is subject to the following [Cohere reranking limits](https://docs.cohere.com/v2/docs/reranking-best-practices#max-number-of-documents):

* `userContext` + `q` combined must stay under 2048 tokens
* Each document sent to the reranker can be at most 32,664 tokens
* The reranker accepts at most 10,000 documents per request, so `limit` cannot usefully exceed 10,000

As a rough guide, one word is about 2 to 3 tokens and a paragraph is about 128 tokens.

## Personalized feeds and placeholder search

When `q` is empty, Meilisearch returns a deterministic set of documents based on ranking rules and filters. The `userContext` can only reorder that fixed set. It cannot change which documents are retrieved.

This has two consequences worth understanding before building a personalized feed:

* Two very different `userContext` values will return the same documents, just in a different order, because the underlying candidate pool is the same for both calls
* Two slightly different phrasings of the same `userContext` can produce different result orders, because the reranker is sensitive to wording

If you need a genuinely personalized candidate set for a homepage feed or infinite scroll, consider these alternatives:

* **Use `userContext` as `q` with full semantic search.** Set `semanticRatio: 1` and pass the `userContext` string directly as `q`. In this case, the `personalize` parameter is not needed: the semantic retrieval already personalizes which documents are returned. Reserve the `personalize` parameter for when the user has typed their own query.

* **Run one search per interest area.** Generate a short list of distinct interest terms from the user profile and run a [multi-search](/references/api/multi-search/perform-a-multi-search) with one semantic query per term. Each query gets its own retrieval pass, so the merged result pool naturally covers more variety. This produces more diverse results but uses more queries.

* **Increase `limit`.** If you keep `q` empty, a higher `limit` gives the reranker a wider fixed pool to reorder within. This is the lowest-effort option but does not change which documents are retrieved.

## Next steps

<CardGroup cols={2}>
  <Card title="Generate user context" href="/capabilities/personalization/how_to/generate_user_context">
    Build dynamic user profiles for more relevant personalized results.
  </Card>

  <Card title="Personalize e-commerce search" href="/capabilities/personalization/how_to/personalize_ecommerce_search">
    Apply search personalization to an e-commerce product catalog.
  </Card>

  <Card title="Recommendations" href="/capabilities/personalization/getting_started/recommendations">
    Build a recommendation system with the similar documents endpoint.
  </Card>
</CardGroup>
