Retrieval Rag

The RAG Scale Cliff: What Breaks Between 100 and 5 Million Documents

0 of 8 complete

0%

Contents

Back|Retrieval RagThe RAG Scale Cliff: What Breaks Between 100 and 5 Million Documents
1/8
49 min left
  1. Home
  2. AI Engineering: Data, RAG and Agents
  3. Retrieval and RAG in Production
  4. The RAG Scale Cliff: What Breaks Between 100 and 5 Million Documents
Related Topics
Retrieval Got Better and the System Got WorseLLM Evaluation and Error AnalysisWho Wrote Your Test Questions?LLM Evaluation and Error AnalysisOne Search System: Stacking the Chapter's Choices and Measuring EachTokens and EmbeddingsThe Score You Had Before Retrieval RanLLM Evaluation and Error AnalysisThe Order You Handed Them InLLM Evaluation and Error Analysis
Next lessonChunking: The First Lever on Retrieval Quality

System Design

1 of 8
  • Foundation
  • Intermediate
  • Advanced
  • Capstone
  • AI Engineering

    • Foundation
    • Data, RAG and Agents
    • Evaluation, LLM Ops and Security

    systemdesign.academy

    • Home
    • Glossary
    • Interview prep
    • Reviews
    • About
    • Pricing
    • Privacy
    • Terms
    • Refunds
    • Delivery
    • Contact

    this free lesson is part of

    AI Engineering

    • 210 lessons in 16 chapters
    • 118 lessons built on a lab that really ran
    • An AI tutor beside every lesson that answers and draws
    • Lifetime access, every new lesson included

    $49 once, by PayPal

    See the AI Engineering course

    Save your progress and get the AI Engineering cheat sheet PDF

    AI Engineering Cheat Sheet: what our labs measured, one rule per result. 12 pages. Free with an account.

    you just read a free lesson from

    AI Engineering

    • 210 lessons in 16 chapters
    • 118 lessons built on a lab that really ran
    • An AI tutor beside every lesson that answers and draws
    • Lifetime access, every new lesson included

    $49 once, by PayPal

    See the AI Engineering course
    Cover of the AI Engineering (LLM applications) interview pack

    Reading for an interview? One lesson is not enough for it.

    Get all 150 questions in the AI Engineering (LLM applications) pack

    Each question has why it is asked, a full answer, what the interviewer listens for, the follow-ups, the common mistakes and a diagram (180 diagrams in all). A PDF you keep, junior to staff level.

    150 questions180 diagramsjunior to staff
    the whole pack₹999 · $20Get the pack Read a free question

    India: UPI, cards or netbanking through Razorpay. Elsewhere: PayPal. Download at once from My packs.

    Why Does a RAG System That Nailed 100 Documents Fail in Production at 5 Million?

    Because the demo was easy in a way nobody noticed, and scale takes that easy away.

    Here is the pattern, told the way it actually happens. A team builds a (RAG) feature. They point it at a folder of a hundred documents, ask it the questions they care about, and it answers every one of them well. The grounding is spot on, the citations are right, the demo lands. They ship it, then they keep feeding it content, because that is the whole point of the product. A hundred documents becomes fifty thousand, then a million, then five. And somewhere in there, without a single deploy that broke anything, the answers get a little worse. Not broken. Worse. Slightly wrong slightly more often.

    The part that makes this dangerous is who notices. Not the dashboards, which stay green. Not the error logs, which stay empty. The users notice, because they are the only ones actually reading the answers. This is the demo-to-production gap, but for retrieval specifically, and it is one of the most common and most confusing failures in applied RAG. Engineers who have shipped these systems describe the same thing again and again: it worked beautifully in the demo, and it quietly degraded as the corpus grew, and for a long time we could not see it.

    Grouped bar chart comparing the same RAG system measured on 100 documents versus 5 million, showing answer accuracy dropping from 97 to 74 percent, grounded-in-right-chunk from 98 to 66, citation correctness from 96 to 70, and recall at 5 from 99 to 55, with a note that nothing errored between the two

    Look at where every number lands. Nothing about the code, the model, or the prompt changed between the two bars. Only the corpus grew. Yet every retrieval-sensitive measurement sags at once, because they are all downstream of the same thing: whether the right chunk made it into the context. A green board and a fast p95 are both perfectly consistent with a system that has quietly lost a third of its recall, and that is exactly the trap.

    This lesson is about exactly why that happens, why your offline evals will not catch it, and what you can actually do about it. The rest of this chapter is the toolbox. This lesson is the map, so here is the map itself: the family of failures a growing corpus produces, all tracing back to one root cause.

    Taxonomy card grid of where a growing corpus breaks RAG, with six cards: recall loss as the core failure, precision loss as the padded context, lost in the middle as the buried answer, eval blindness as why nobody sees it, cost and latency creep as the price of fighting back, and chunking debt as the foundation crack

    Read those six cards as one story seen from six angles. Recall loss is the engine, and everything else is a consequence or a complication of it. The whole rest of the lesson walks these cards one at a time, shows you how to see each one, and then hands you the levers that fight back.

    after “Why Does a RAG System That Nailed 100 Documents Fail in Production at 5 Million?”

    This is the part interviews go deep on.

    In the AI Engineering course, the next step is The RAG Retrieval Cliff: Engineering Recall Back at Scale.

    It starts from the problem and builds up to the design one step at a time.

    Open the AI Engineering course page

    Why Does RAG Retrieval Get Worse at Scale?

    Because retrieval is a competition for a small number of spots, and a bigger corpus means more competitors, most of them wrong.

    Walk through the mechanism, because the whole lesson rests on it. When a query comes in, you turn it into a vector, and you ask the vector index for the chunks whose vectors are nearest to it. You keep a small number of them, the top k, usually somewhere between three and ten, and those become the context you hand the model. That number k does not grow when your corpus grows. You still take the top few, whether you are searching a hundred chunks or five million.

    Now think about what is near the query in vector space. At a hundred documents, the neighborhood around any query is nearly empty. The chunk that actually answers the question has almost no competition, so it lands in the top k basically every time. At five million documents, that same neighborhood is crowded. There are now thousands of chunks that are close to the query, semantically in the same area, worded similarly, on the same topic, and almost all of them are wrong. They are plausible-but-wrong near neighbors, and they did not exist at demo scale. The answer chunk now has to beat all of them to stay in the top k.

    Two-panel scatter plot in a projected vector space, left panel labeled 100 documents showing a query star with a single answer chunk sitting alone inside a dashed top-k ring, right panel labeled 5 million documents showing the same query and answer chunk now surrounded by dozens of red near-miss points crowding the same ring and pushing the answer out

    The answer chunk never moved. Its neighborhood filled up. That is the entire mechanism in one picture. The dashed ring is the top k the model gets, and on the right the near-misses have crowded inside it, elbowing the right chunk toward the edge and then past it. This is not a failure of the model or the index. It is the geometry of a high-dimensional space that has simply become dense in the region your query points at.

    Two things fall as a direct result. Recall@k falls: the fraction of the time the answer chunk is actually inside the top k goes down, because more competitors can push it out. And precision falls: more of the chunks you do retrieve are near-misses, so the context you feed the model is padded with confident, on-topic, wrong material it has to see past. Neither of these throws an error. Both of them make the final answer worse.

    Horizontal retrieval pipeline with five stages, query then embed then ANN top-k then context then LLM answer, every stage marked ran fine with a green check, and a red silent-failure banner explaining that no stage throws and no log records the miss because the error lives only in the gap between the answer chunk and the top-k that was returned

    Can You Actually See Recall Fall as the Corpus Grows?

    Yes, and you can watch it happen in a few lines. The block below is a small simulation of exactly the effect described above, with no machine learning and no external service, just vectors and .

    The setup mirrors the mechanism. For each trial, we make a random query direction. The chunk that holds the answer is placed very close to the query, so at small scale it is easily the nearest. Then we add distractor chunks, the plausible-but-wrong near neighbors, scattered around the same query, a bit further out than the answer chunk. We measure recall@3: across many trials, how often is the answer chunk in the top three by cosine similarity? Then we do it again with a much larger pile of distractors and watch the number fall.

    Read the output as a curve. At 20 documents the answer chunk is in the top 3 almost every single time. Add near-misses and the number slides: it is meaningfully lower by a few hundred documents and roughly half by a few thousand. In this simulation, recall@3 falls from about 0.99 at 20 documents to about 0.5 at 5000. Nothing about the answer chunk changed between the two runs. It sits in the exact same place relative to the query. The only thing that changed is how many wrong chunks are now crowding the same neighborhood, and that alone is enough to knock the right one out of the top k. That is the cliff, and it is a property of the geometry, not a bug in your code.

    Line chart of recall at 3 versus corpus size on a logarithmic x-axis, solid red line for measured simulation values falling from 99 percent at 20 chunks through 88, 68, and 52 percent to 41 percent at 20 thousand, then a dashed amber illustrative continuation sinking below 20 percent by 5 million, with a shaded coin-flip band under 50 percent

    Plotted, the fall is unmistakable, and the log x-axis matters: corpora grow by multiples, not by additions, so a jump from ten thousand to a million is only two steps along this axis. The solid points are what the simulation actually produced on a laptop. The dashed tail is illustrative, an extrapolation of the same geometry to millions, but its direction is not in doubt. Once recall crosses into the shaded band under fifty percent, the system is retrieving the right chunk less often than a coin flip.

    Recall is only half of the damage. The other half is what surrounds the answer chunk when it does survive. Hold the top k fixed and watch the composition of those k slots change as the corpus grows.

    Stacked horizontal bars showing the composition of a fixed top-5 as the corpus grows, at 20 documents all 5 are relevant, at 1000 it is 3 relevant and 2 near-misses, at 5000 it is 2 relevant and 3 near-misses, and at 5 million it is 1 relevant chunk padded by 4 near-misses

    If Recall Is Falling, Why Do My Offline Evals Still Pass?

    Because your offline eval is almost certainly testing the one part of the system that does not degrade.

    Think about how a retrieval eval usually gets built. Early on, when the corpus is small, someone writes a set of questions, maybe fifty, maybe a couple hundred, and checks that the system answers them well. That set gets frozen and run on every change as the offline eval. The problem is what those questions are. They are questions the team knew the answers to, drawn from the corpus as it was then, and they were chosen precisely because they worked. Their answer chunks are distinctive and easy to retrieve, and distinctive chunks stay easy to retrieve even as the corpus grows around them. So those questions keep passing. Forever. They were never the ones at risk.

    Coverage map of all real user queries against the full corpus drawn as a large red field scattered with failing-query crosses, and a small green dashed ellipse labeled frozen eval set of 150 distinctive questions still passing at 100 percent, sitting in one corner while the long tail of failures spreads across the uncovered rest of the field

    The regression lives somewhere your eval never looks: the long tail of real queries you never wrote a test for, run against the full corpus with all its near-misses. That is the wide red field in the picture, and it is where recall actually falls. The little green island is your frozen eval, walking the easy path over and over and reporting that it is still easy. A green offline board is not telling you the system is healthy. It is telling you that the easy path is still easy, which was never in doubt.

    There is a matching trap on top of the recall problem, and it is worth naming because it makes things worse. Even when the answer chunk does survive into the top k, it can land in the middle of a long context, surrounded by near-misses. Models do not read a long context evenly. In the paper that named the effect, "Lost in the Middle," Liu and colleagues measured that models perform best when the relevant information is at the very start or the very end of the context and worst when it sits in the middle, so a correct chunk buried in the middle is often skipped (Liu et al., 2023).

    U-shaped line chart of answer accuracy versus the position of the answer chunk in the context, high near 95 percent at the start and end, dipping to about 62 percent in the middle where models attend least, with the middle region shaded and marked worst here, after Liu et al 2023

    So scale hurts you twice. It pushes the answer chunk out of the top k, and when it does survive, the near-misses padding the context can bury it in the middle, exactly where the model is least likely to use it. A correct chunk in the wrong position is still a wrong answer. This is a second reason more context is not safer: a longer context has a bigger middle to get lost in, and stuffing it fuller of near-misses makes that middle more crowded.

    What Does This Failure Look Like Month to Month?

    Like nothing, for a long time, and then like a mystery.

    The reason the scale cliff burns teams is not that it is severe. It is that it is slow and silent, so by the time it is visible it has been happening for months and points at no obvious cause. There was no bad deploy to roll back. The model did not change. The prompt did not change. The corpus just kept growing, which is the one thing the product was designed to do.

    Slow-motion failure timeline over twelve months, a red line for true retrieval quality declining steadily from launch while a green line for the curated eval signal stays nearly flat near the top, with markers for corpus keeps growing at month one, users start noticing at month five, thumbs-down rises at month eight, and someone investigates at month ten

    Follow the two lines and notice the gap between them. Retrieval quality begins slipping from the first month the corpus grows, but the signal the team watches stays green because the curated questions never got harder. The distance between the red line and the green line is the danger: it is how long the system was quietly degrading before anyone could name it. The people who feel the slide are users, and they feel it in the worst possible form for debugging: answers that are subtly wrong slightly more often. There is no crash to attach a ticket to, just a slow drift in thumbs-down rates and support volume that takes months to rise above the noise. When someone finally asks why quality fell, the honest answer is that nothing broke. The system did exactly what it was built to do, ingest more content, and got worse at retrieval as a direct result.

    To make the mechanism concrete, here is the same story told as the life of a single query's top k as the corpus grows around it.

    State progression showing the life of one query's top-3 slots across five states, recovered on the left as the target with the answer chunk in the top slot, then clean, then near-miss creeps in, then buried where the answer is retrieved but ignored mid-context, then dropped where the answer falls out of the top-k entirely and all three slots are near-misses

    It starts clean, picks up a near-miss, then reaches the state that fools everyone: the answer is still retrieved but buried where the model does not read it, so the answer is wrong even though retrieval technically worked. Grow the corpus further and the answer chunk drops out of the top k entirely. Each of those transitions is invisible from the outside, and two of them, buried and dropped, produce a wrong answer with no error anywhere in the system. The recovered state on the far left is where the rest of this chapter is trying to get you, and the only way to know which state a query is in is to measure it deliberately.

    So What Actually Pushes Back Against the Cliff?

    Four levers, and every one of them does the same underlying job: it either shrinks the field the answer chunk has to compete in, or it sharpens the ranking so the answer chunk rises to the top few the model actually reads.

    Layered stack of the four levers on a chunking foundation, metadata filtering shrinks the field with the cost that it needs clean metadata, hybrid retrieval sharpens the ranking at the cost of operating two systems, a tuned ANN index buys headroom at the cost of a recall-versus-speed knob, reranking sharpens the ranking at the cost of latency and a second model, all sitting on a dark chunking foundation block

    Take them from the top of the stack. Metadata filtering is often the cheapest lever when your data carries clean, trustworthy fields to filter on: if you can restrict the search to chunks that match a structured field, such as the tenant, the product, the language, or the date range, before any vector comparison runs, you cut the candidate set from millions to thousands, and the answer chunk suddenly has far fewer near-misses to beat. Hybrid retrieval runs a keyword search alongside the vector search and merges the results, which rescues the queries pure embeddings handle worst: exact identifiers, rare terms, and part numbers that a semantic model smears together. A purpose-built index, such as HNSW or IVF, keeps the search fast enough at scale that you can afford a wider candidate set and a second pass on top of it. And reranking is that second pass: you pull a wide net, say the top fifty, and rescore each candidate against the query with a heavier cross-encoder model, then keep the best few. Reranking is the direct attack on precision, because the first stage only has to get the answer chunk into the top fifty, and the reranker lifts it into the top few.

    Notice the cost tag on every layer, because none of this is free. adds a second model and milliseconds to every query. Hybrid means you operate and tune two retrieval systems. Metadata filtering only helps if your metadata is actually clean and trustworthy. A tuned index has a recall-versus-speed knob you have to keep tuned. The right amount of each depends on how large your corpus really is and how wrong an answer is allowed to be.

    Underneath all four sits chunking, the decision of how you split documents into the units you embed in the first place. It is the foundation because every lever above operates on the chunks you chose. If the answer is split across two chunks, or drowned inside one giant chunk, no index and no reranker can retrieve it cleanly. That is why the next lesson in this chapter starts exactly there, with chunking, and then works up the stack through the others.

    Does This Mean pgvector Is Wrong and I Need a Fancy Vector Database?

    No, and anyone who tells you the fix is a specific product is selling one.

    Here is the honest version. A simple setup, Postgres with the pgvector extension or a small hosted vector store, is genuinely fine well past the demo. Plenty of real products run on exactly that. What the scale cliff tells you is not "your store is wrong," it is that raw nearest-neighbor search over a growing corpus loses recall no matter whose store is running it, because the effect is geometric, not vendor-specific. Swapping to a different does not repeal the math. What carries you past the cliff is the combination on the previous slide: good chunking, a well-tuned approximate index, hybrid retrieval, reranking, and metadata filtering to shrink the space. A specialized vector database can make some of those easier or faster to run at very large scale, and that is a real reason to reach for one, but the technique is what moves recall, not the logo.

    So how do you decide what to add and when? Not all at once, and not because a benchmark chart says so. Walk the symptoms and add the cheapest lever each one demands, stopping at the first match.

    Decision flow for when RAG needs re-architecting, walked top to bottom stopping at the first match, small corpus with recall holding means naive RAG is fine, recall falling on the long tail means add reranking, exact IDs or rare terms failing means add hybrid retrieval, clean structured fields available means add metadata filtering, and millions of vectors with latency or memory hurting means tune the ANN index or move stores

    Most teams start naive and add one lever at a time as a real number forces it. If your corpus is small and recall is holding on real queries, do not add complexity you cannot yet measure a need for. If recall is falling on the long tail, is usually the biggest single win. If exact identifiers and rare terms are failing, that is a hybrid-retrieval problem, not a bigger-index problem. Only when you are into the millions of vectors and latency or memory is genuinely hurting does tuning the approximate index or reaching for a specialized store earn its complexity.

    Every one of these levers has a cost worth stating plainly. Reranking adds latency and a second model to run, so it costs money and milliseconds on every query. means you now operate and tune two retrieval systems instead of one. Metadata filtering only helps if your data actually has clean, trustworthy metadata to filter on, which is its own data-quality problem. A bigger approximate index has a recall-versus-speed knob that you have to tune and keep tuned. None of this is free, and the right amount of it depends on how large your corpus really is and how wrong an answer is allowed to be. The trap to avoid is the opposite one: shipping the naive demo to production and assuming it will hold, because it will not, and the failure will be silent.

    Knowledge Check

    Knowledge Check

    4 questions - Score 80% to pass

    Q1

    A RAG feature answered every demo question well on 100 documents. At 5 million documents, users report answers are subtly wrong more often, but the error logs are empty and latency is fine. What is the most likely root cause?

    Q2

    Your frozen offline eval of 150 questions still passes at 100% after the corpus grew 50x. Why does that not prove retrieval is healthy?

    Q3

    Even when the answer chunk IS retrieved into the top k, why can scale still cause a wrong answer?

    Q4

    A vendor tells you their vector database will fix your scale cliff. What is the honest assessment?

    The red banner is the whole story. Every step in that pipeline runs perfectly. The query gets embedded, the index returns its top k, the chunks become context, the model writes a fluent answer. If the answer chunk was not in that top k, nothing anywhere reports a problem. The model just grounds its answer in the wrong material and sounds completely sure about it. Your observability stack watches errors, , and throughput, and none of those three ever moves, because the failure is a ranking miss inside a step that succeeded.

    At demo scale nearly every retrieved chunk is genuinely relevant, so the model reads a clean context. At production scale a single good chunk arrives padded out with four confident, on-topic, wrong ones. The model cannot tell your one good chunk from the four near-misses, so it averages over all of them, and the answer drifts even when recall technically held. This is precision loss, and it is why simply retrieving more chunks to be safe usually makes answers worse rather than better.

    The fix is not a better dashboard. It is a retrieval-specific eval: a labeled set drawn from real traffic, where you know which chunk should be retrieved for each query, and you measure recall@k against it as the corpus grows. That is a whole topic of its own, and it ties directly to the evals chapter, but the point here is that your general offline eval will sit there green while all of this happens.

    after “So What Actually Pushes Back Against the Cliff?”

    The free lesson gives you the outline. A lesson gives you the working.

    The AI Engineering course gives this its own lesson: Chunking: The First Lever on Retrieval Quality.

    Plain English first, then the detail, then a quick check that you got it.

    See the AI Engineering course

    The one thing you should walk away certain of is this. A system's quality is capped by its retrieval, retrieval degrades as the corpus grows, and that degradation is invisible to the metrics most teams watch. Everything else in this chapter is how you measure it and fight it.

    after “Does This Mean pgvector Is Wrong and I Need a Fancy Vector Database?”

    Could you draw this on a whiteboard tomorrow?

    The lesson that covers it: Reranking: The Highest-Return Change in Your RAG Stack, in the AI Engineering course.

    About 55 minutes, and you can stop and come back any time.

    Look inside the AI Engineering course $49 once, lifetime access