AI Workflow Agency
AI5 min read

MRR in RAG: What Mean Reciprocal Rank Actually Measures

MRR (Mean Reciprocal Rank) is a core retrieval metric for RAG pipelines

By AI Advisory team

If you have started evaluating a Retrieval-Augmented Generation (RAG) system, you have almost certainly run into MRR. It sits alongside Recall@k, nDCG, and Hit Rate in every retrieval evaluation toolkit, and it is one of the first numbers a well-run RAG team watches move as they tune their pipeline.

MRR stands for Mean Reciprocal Rank. It is a metric borrowed from classical information retrieval (it predates RAG by about thirty years) and it answers a very specific question: on average, how far down the ranked list do we have to look before we hit a correct result? In a RAG context, that translates to: how quickly does our retriever surface a chunk that actually answers the user's question?

This article walks through what MRR is, how to compute it, why it matters specifically for RAG, where it misleads you, and how to use it alongside other metrics without getting a false sense of quality.

The definition, without hand-waving

Reciprocal Rank for a single query is defined as 1 / rank_of_first_relevant_result. If the first relevant document is at position 1, RR = 1.0. Position 2 gives 0.5. Position 3 gives 0.333. Position 10 gives 0.1. If no relevant document appears in the top-k results you retrieved, RR = 0 for that query.

Mean Reciprocal Rank is simply the mean of RR across an evaluation set of queries:

MRR = (1/N) * Σ (1 / rank_i)

Where N is the number of queries and rank_i is the position of the first relevant result for query i. That is the whole formula. There is no weighting scheme, no discount factor, no logarithm. It is deliberately blunt.

Two properties fall out of the definition and are worth internalising before you start using MRR to make decisions:

  • MRR only looks at the first relevant result. If your retriever returns ten chunks and three of them are relevant, MRR only cares where the highest-ranked relevant one sits. The other two are invisible to this metric.
  • MRR punishes lateness harshly at the top and gently after that. Moving from rank 1 to rank 2 costs you 0.5. Moving from rank 9 to rank 10 costs you 0.011. This is by design - most consumers of ranked results care disproportionately about the top positions.

These two properties are why MRR is a natural fit for RAG evaluation, and also why it is dangerous to use on its own.

Why MRR matters for RAG specifically

A RAG pipeline typically retrieves the top k chunks (usually 3 to 20) from a vector store, optionally re-ranks them, and passes them into the context window of an LLM. The generator then produces an answer grounded in those chunks.

Here is the awkward truth about how modern LLMs read retrieved context: they do not read it uniformly. Research from Anthropic, Stanford, and others has repeatedly shown a "lost in the middle" effect - LLMs pay disproportionate attention to the beginning and end of their context window, and glaze over the middle. The Liu et al. (2023) "Lost in the Middle" paper is the canonical reference here and worth reading if you have not.

The practical implication: even if your retriever surfaces a relevant chunk somewhere in the top-10, if it lands at position 5 or 6, the LLM may effectively ignore it. Getting the right chunk into position 1 or 2 is not a nice-to-have - it materially affects whether your generator produces a grounded answer or a hallucination.

MRR captures exactly this concern. A retriever with MRR = 0.9 is putting the correct chunk at or near the top almost every time. A retriever with MRR = 0.4 is putting it, on average, around position 2 or 3, which is workable but leaves generation quality on the table. A retriever with MRR = 0.15 is putting it around position 6 or 7 - your generator is probably hallucinating and you are probably blaming the LLM when the fault is upstream.

This is the core reason MRR earns its place in RAG evaluation. It maps directly to whether the LLM can see the answer.

Worked example

Suppose you have a small evaluation set of five queries against a knowledge base of company policy documents. For each query, you have a hand-labelled "gold" chunk that contains the correct answer. You run your retriever and record the rank at which the gold chunk appears in the top-10 results.

  • Q1: "What is our parental leave policy?" - gold chunk at rank 1. RR = 1.0
  • Q2: "How do I expense a client dinner?" - gold chunk at rank 3. RR = 0.333
  • Q3: "What is the notice period for a senior engineer?" - gold chunk at rank 2. RR = 0.5
  • Q4: "Can I work from abroad for a month?" - gold chunk not in top-10. RR = 0
  • Q5: "How do I book study leave?" - gold chunk at rank 1. RR = 1.0

MRR = (1.0 + 0.333 + 0.5 + 0 + 1.0) / 5 = 0.567

That number, on its own, tells you the retriever is reasonable but has clear failure modes: one query missed entirely, and one where the correct chunk sits at rank 3 (likely to be ignored by the generator under "lost in the middle" conditions). Both are actionable. You would probably investigate Q4 first (why did the retriever miss entirely?) and then look at Q2 (is there a chunking issue, an embedding mismatch, or a legitimate ambiguity in the query?).

How to build the evaluation set

MRR is only as useful as the evaluation set you compute it against. Building that set is the part most teams skip and then regret. A few practical rules from running these evaluations for clients:

Use real queries, not synthetic ones. Pull the actual queries hitting your system from logs. If you have not launched, pull queries from support tickets, sales-call transcripts, or Slack channels where the target users already ask this kind of question. LLM-generated synthetic queries are fine as a supplement, but they systematically miss the messy phrasing, typos, and half-formed questions real users produce.

Label at the chunk level, not the document level. RAG retrieves chunks. If you label "document X is relevant to query Q" but chunk 3 of document X is the only one that actually contains the answer, your MRR will be inflated - the retriever might surface chunk 7 (which mentions the topic but does not answer) and you would count that as a win when the generator will produce a bad answer.

Aim for at least 100 queries per major query category. MRR on 20 queries is directionally useful but noisy. On 100+ queries you can start to trust the number and slice by category (product questions vs policy questions vs troubleshooting) to find where the retriever is weak.

Refresh the set every quarter. User query patterns drift, especially in the first year of a deployed RAG system as users learn what it can do.

Where MRR misleads you

MRR is a good metric. It is not a sufficient one. The most common ways it will steer you wrong:

It ignores multiple relevant chunks. Complex questions often need synthesis across two or three chunks - a pricing question that requires the base price chunk plus the current promotion chunk plus the T&Cs chunk. MRR only measures whether one of them was ranked highly. Recall@k and nDCG capture this better. For synthesis-heavy use cases, MRR alone will make a bad retriever look fine.

It is insensitive below the top few positions. A retriever that consistently puts the correct chunk at rank 8 vs rank 10 will show barely any difference in MRR (0.125 vs 0.1), but that difference may or may not matter to your generator depending on your context strategy. If you are only passing top-3 into the LLM, both retrievers are equally broken.

It says nothing about generation quality. You can have MRR = 0.95 and still produce terrible answers - because your chunking is wrong, your prompt is wrong, your model is undersized, or your refusal patterns are missing. MRR measures retrieval, not RAG. Do not confuse the two.

It does not measure faithfulness. A retriever can put the right chunk at rank 1 and the generator can still hallucinate around it. You need separate faithfulness / groundedness metrics (RAGAS, TruLens, or custom judge-model evaluations) to catch that.

What to pair MRR with

A defensible RAG evaluation stack, in our experience running builds for mid-market clients, looks something like this:

  • MRR - how quickly does the top relevant chunk surface? Best for single-answer questions.
  • Recall@k (typically k=5, 10, 20) - what fraction of the relevant chunks are in the top-k? Best for synthesis questions.
  • nDCG@k - like MRR but accounts for multiple relevant results and graded relevance. Slower to compute and interpret, but more informative when you have graded labels.
  • Faithfulness (RAGAS or similar) - does the generated answer stay within what the retrieved chunks actually say?
  • Answer correctness - a judge model or human evaluator scoring whether the final answer is right.
  • Refusal rate - how often does the system correctly decline to answer when the retrieved chunks do not support an answer? Often the most neglected metric.

Track all six on every meaningful change to the pipeline. If MRR goes up but faithfulness goes down, you have chosen a retriever that surfaces plausible-looking chunks that do not actually contain the answer. That is a common failure mode when you switch from lexical (BM25) to dense retrieval without tuning.

Practical targets to aim for

These are rough numbers from RAG systems we have shipped into production - treat them as starting benchmarks, not universal truths. Your domain will shift them.

  • MRR < 0.4: your retriever is not usable. Investigate chunking, embedding model choice, and whether your query rewriting step is helping or hurting.
  • MRR 0.4-0.65: workable for internal tools where users tolerate some browsing. Not ready for customer-facing.
  • MRR 0.65-0.85: production-grade for most enterprise use cases. Pair with a re-ranker (Cohere Rerank, BGE reranker, or a fine-tuned cross-encoder) to push higher.
  • MRR > 0.85: strong. Focus your remaining evaluation effort on faithfulness and refusal, not retrieval.

The jump from 0.65 to 0.85 usually comes from a re-ranker or hybrid (lexical + dense) retrieval, not from swapping embedding models. The jump from 0.85 upwards usually comes from better chunking or query rewriting, not from bigger models. If you find yourself trying to fix retrieval by moving from text-embedding-3-small to text-embedding-3-large, you are usually looking at the wrong lever.

Frequently asked questions

Is MRR the same as Mean Average Precision (MAP)?

No, though the two are often confused. MRR only considers the position of the first relevant result and ignores everything after it. MAP averages precision across all positions where a relevant result appears, so it rewards retrievers that surface multiple relevant chunks throughout the ranking. Use MRR when your generator only needs one correct chunk to answer well (typical for factual Q&A). Use MAP or nDCG when your generator needs to synthesise across multiple chunks (typical for summarisation, comparison, or multi-hop questions).

What is a good MRR score for a production RAG system?

Depends heavily on your domain and how well-defined your queries are, but as a working benchmark: 0.65-0.85 is production-grade for most enterprise knowledge-base and support-bot use cases, 0.85+ is strong, and anything below 0.4 usually means the retrieval pipeline needs structural work rather than tuning. Customer-facing systems generally need higher MRR than internal tools because end users have less patience for wrong answers and less context to catch retrieval failures themselves.

Does MRR account for the "lost in the middle" effect in LLMs?

Indirectly, yes - and this is one of the strongest arguments for using it. Because MRR rewards putting the correct chunk at rank 1 or 2 far more than at rank 5 or 6, it aligns well with the observation that LLMs attend most strongly to the start of their context window. A retriever optimised for high MRR is, by construction, one that puts important content where the generator will actually read it. That is not a coincidence - it is a happy accident of a metric designed thirty years before LLMs existed.

How many queries do I need in my evaluation set for MRR to be reliable?

For a headline number you can trust to within a couple of percentage points, aim for at least 100 queries. For slicing by category (product vs policy vs troubleshooting, say) you want 100+ per slice. Below 30 queries the number is directionally useful but noisy enough that you can be fooled by run-to-run variance. Build the set once properly, version it, and reuse it - the cost of building a good 200-query eval set pays back within the first two retriever iterations.

Can I compute MRR without hand-labelled data?

Partially. You can generate synthetic query-chunk pairs by asking an LLM to generate a plausible question given a specific chunk, then measuring whether your retriever surfaces that chunk when the query is used. This gives you a proxy MRR without human labelling. It is useful for rapid iteration but tends to overestimate real-world performance because synthetic queries are cleaner and more on-topic than real user queries. Use synthetic MRR to detect regressions in CI; use hand-labelled MRR for anything you plan to make a decision on.

Does MRR work for multi-turn or conversational RAG?

The core metric still applies, but you need to be careful about what "the query" is. In conversational systems, the retriever usually operates on a rewritten query that combines the current turn with prior context. Your MRR evaluation should include the rewrite step, not just the final retrieval - otherwise you are measuring the retriever in isolation from how it actually gets used. A retriever with excellent standalone MRR can still perform badly if the query rewriter mangles the conversation history before retrieval.

Should I optimise directly for MRR or for downstream answer quality?

Optimise for downstream answer quality, but use MRR (and Recall@k) as fast proxies during iteration. Full end-to-end answer evaluation with a judge model is slow and expensive - you cannot run it on every pipeline change. Retrieval metrics are cheap to compute and correlate strongly with answer quality when the rest of the pipeline is stable. The workflow: iterate on retrieval using MRR + Recall@k, then validate the winning configuration end-to-end with faithfulness and correctness metrics before shipping.

Closing thought

MRR is one of the sharpest, simplest metrics you can put on a RAG retriever, and it maps unusually well to how LLMs actually consume retrieved context. It is also easy to mislead yourself with if you use it alone - it says nothing about synthesis, faithfulness, or refusal behaviour, and it can be gamed by retrievers that surface plausible-looking chunks that do not contain the answer. Treat it as one dial on a dashboard of five or six, and you will make better decisions than teams who either ignore retrieval evaluation entirely or fixate on a single number.

If you are building a RAG system and want an evaluation harness that catches these failure modes before your users do, AI Advisory has shipped this kind of infrastructure for mid-market clients across financial services, legal, and B2B SaaS. Get in touch if you would like to talk through your setup.

Further reading

Sources referenced for context not directly cited in the body:

Ready to put this into production? book a discovery call.

Get started

Ready to automate your operations?

Walk away with a prioritised list of automation and AI wins, costed, sequenced, and yours. The call is 30 minutes, free, and binds you to nothing. The shortest path to knowing whether AI Workflow Agency is the right fit.