The Latency Budget
A RAG request moves through three sequential stages, each contributing to the total response latency the user experiences. Understanding each stage separately is the first step toward optimizing the overall system.
Embedding stage (target: 10ms): The user query is encoded into a dense vector. With a model like Sentence-BERT running on GPU, this typically takes 5-15ms for a single query. Batching requests can improve throughput but adds queuing latency for individual users.
Retrieval stage (target: 20ms): The query vector is compared against the index to find top-k chunks. With FAISS on a million-document index running locally, ANN search typically takes 5-30ms depending on index type and the value of k. Managed vector databases like Pinecone add network round-trip time but handle horizontal scaling automatically.
Generation stage (target: 200-500ms): The assembled context and query are sent to the language model for response generation. This dominates the latency budget. Token generation speed depends on model size, hardware, and context length. For conversational RAG, users typically tolerate up to 3-5 seconds end-to-end; for batch workflows, throughput matters more than latency.
Caching Strategies
Caching is the highest-leverage optimization available for a deployed RAG system. Real-world usage shows significant query repetition: users in the same organization tend to ask similar questions, and many queries repeat verbatim across sessions.
Semantic caching is the most powerful layer but also the most complex to tune. A threshold too high misses paraphrases; a threshold too low conflates distinct questions. Start with exact-match caching for immediate gains, then layer in semantic caching once you have query logs to validate threshold choices.
Metadata Filtering
Vector similarity search compares every indexed chunk against the query vector by default. For a 5-million-chunk index, this is computationally expensive. Metadata filtering limits the search to a relevant subset before similarity comparison.
Consider a legal document system with chunks tagged with document_type, jurisdiction, and year. A query about California employment law in 2024 should search only chunks where jurisdiction="CA" and document_type="employment". This pre-filter might reduce the search space from 5 million chunks to 40,000, dramatically reducing retrieval cost and improving precision.
Most managed vector databases support metadata filtering natively. FAISS requires maintaining a separate metadata store and filtering chunk IDs before search. Weaviate and Pinecone integrate filtering directly into the vector search query, pushing the filter to the index level for maximum efficiency.
Audit the metadata currently attached to your chunks. Common high-value metadata fields: source_url, created_date, document_type, department, language. Pick one field that would meaningfully reduce your search scope for 70% of real user queries, and add a filter on that field to your retrieval call.
Observability
A RAG system without observability is a black box. You cannot improve what you cannot measure, and problems invisible in development often surface at scale.
Log every retrieved chunk alongside the query and generated answer. This creates a dataset for offline evaluation: you can run RAGAS (Module 5) over production logs weekly to detect faithfulness drift before users notice it.
Track retrieval latency per stage separately: embedding time, vector search time, generation time, and total response time. Sudden increases in any single stage point directly to the bottleneck.
Monitor faithfulness as a moving average. Compute faithfulness scores on a random 5% sample of production queries. A drop in faithfulness from 0.88 to 0.72 over two weeks indicates either document drift (the knowledge base is stale) or prompt drift (a prompt change caused the model to hallucinate more).
Flag no-retrieval answers. When the retriever returns zero relevant chunks (all similarity scores below threshold), log the query. Clusters of these queries indicate coverage gaps in your knowledge base that need new content, not engineering fixes.
Advanced Retrieval Patterns
Standard dense retrieval works well for direct questions but struggles with abstract or hypothesis-driven queries. Three advanced patterns address specific failure modes.
HyDE (Hypothetical Document Embeddings): Instead of embedding the query directly, ask the LLM to generate a hypothetical document that would answer the query. Embed that document and use it as the search vector. HyDE shifts the embedding from query-space into document-space, which can dramatically improve recall for complex or abstract questions. The cost is one extra LLM call per query before retrieval.
FLARE (Forward-Looking Active Retrieval): FLARE generates the response token by token and triggers a new retrieval whenever the model is uncertain about an upcoming claim (measured by token probability). It is a dynamic retrieval pattern rather than a one-shot retrieve-then-generate approach. FLARE is particularly effective for multi-hop questions requiring information from multiple documents.
Self-RAG: A fine-tuned model that generates special tokens during generation to decide whether to retrieve, evaluate the quality of retrieved chunks, and assess whether its own output is grounded. Self-RAG internalizes the retrieval decision rather than relying on the pipeline structure. It requires a specialized fine-tuned model but reduces unnecessary retrieval calls for queries the model can answer from parametric knowledge.