Skip to content
datarekha

Chunking for RAG

A retriever cannot find context that your chunks destroyed. Learn how chunk size, overlap, document structure, semantic boundaries, and parent-document retrieval change both retrieval quality and LLM answers, with numbers, failure symptoms, and a production workflow.

Written and reviewed by Last reviewed

12 min read Intermediate Generative AI Lesson 18 of 73

What you'll learn

  • Why chunking changes both the embedding signal and the context an LLM receives
  • How chunk size and overlap trade retrieval precision, context, index size, and latency
  • When fixed, sentence-aware, structure-aware, semantic, or parent-document chunking fits
  • How to diagnose bad chunking from the first symptom and measure improvements with retrieval evals

Before you start

At 3:07 a.m., someone asks your internal support bot:

Can a contractor approve a refund above $500?

The answer is in the company handbook. It is one sentence under a heading that says Contractor purchases. Your system retrieved the sentence, but not the heading. The model confidently answers, “Yes, managers can approve refunds above $500,” because a nearby paragraph described managers. The retrieval score looked healthy. The answer is still wrong.

This is the problem chunking exists to solve.

A document arrives as a page, PDF, Markdown file, transcript, or database record. Before a RAG system can embed and index it, you split it into chunks: pieces of text that will be matched against a user’s question. A good chunk is small enough to match precisely and large enough to carry the meaning needed for an answer.

That sounds like housekeeping. It is not. If the relevant fact is mixed with noise, or its qualification is cut away, a better embedding model cannot reconstruct what you threw out.

TryChunking strategies

How chunking changes what gets retrieved

The document below is split four ways. Pick a strategy to see the chunk boundaries; the highlighted chunk is what retrieval returns for the sample query. Notice when fixed-size splitting breaks the answer across two chunks.

query"What encryption does Northwind use for data at rest?"

Split every 256 tokens regardless of sentence or paragraph boundaries.

Northwind Cloud is a managed data platform that runs entirely on your existing cloud provider account. You bring the infrastructure; we bring the orchestration layer.

To get started, install the northwind CLI and run northwind init. The wizard will ask for your AWS or GCP credentials, create the necessary IAM roles, and provision a small control-plane cluster.

The platform currently supports three compute engines: Spark for batch workloads, Flink for streaming, and DuckDB for ad-hoc OLAP queries under 100 GB. All three share the same catalog and storage layer.

Data security is handled at two levels. At rest, all tables are encrypted using AES-256-GCM with keys you manage in AWS KMS or GCP Cloud KMS — Northwind never sees your encryption keys.

retrieved

In transit, all connections use mutual TLS 1.3. You can optionally enable private link so that traffic never leaves your cloud provider's backbone network.

Pricing is based on compute hours consumed, not data volume. Spark and Flink jobs are billed at $0.08 per vCPU-hour; DuckDB queries are metered at $0.004 per GB scanned, with the first 100 GB per month free.

Support tiers: Community (forum only), Developer ($299/mo, 8-hour response), and Enterprise (24/7, one-hour SLA for P1 incidents, dedicated Slack channel).

Northwind is open-core: the control plane and catalog are source-available under the Business Source License. The compute adapters and storage connectors are fully open-source under Apache 2.0.

Fixed-sizeRetrieves chunk 2, which has only the first half of paragraph 3. The key detail about KMS spilled into chunk 3 — the answer is split across two chunks.
Chunking decides whether the right context survives intact. Fixed-size splitting (the default in most tutorials) fragments meaning; paragraph-aware, semantic, or parent-doc strategies keep co-located facts together so retrieval can find a complete answer.

What a chunk does to retrieval

A typical RAG retriever does not compare a question with an entire 40-page handbook. It compares the question with indexed chunks.

First, an embedding turns each chunk into a vector representing patterns in its meaning. The question gets its own vector. The retriever ranks chunks whose vectors are most similar to the question vector, and the top results become context for the LLM.

That gives each chunk two jobs:

  1. It must contain enough signal to match the question.
  2. It must contain enough context to support the answer.

Large chunks often fail the first job. Small chunks often fail the second.

Imagine a deliberately simple embedding with two dimensions: “refund policy” and “general billing.” A 200-token chunk contains 40 tokens about refund approval and 160 about unrelated billing procedures. In this toy arithmetic, refund material makes up 20 percent of the chunk. An 800-token chunk containing the same 40 relevant tokens has only 5 percent refund material.

Real embeddings are not literal word-count averages. But the intuition holds: mixing unrelated ideas makes a chunk’s representation less specific. A refund query may now compete with queries about invoices, payment dates, and billing addresses. The noisy chunk is harder to retrieve and, once retrieved, wastes context-window space.

At the other extreme, a 35-token chunk might say:

Refunds above $500 require director approval.

If the heading and previous sentence say that this applies only to contractor purchases, the chunk matches the query while omitting its scope. It is locally precise but globally misleading. Chunking determines the unit of meaning that retrieval can see.

Size and overlap, with actual numbers

A fixed-size chunker chooses a window of size tokens and moves forward by size - overlap tokens. Overlap is the repeated text at the edge of consecutive chunks.

doc = "RAG retrieves relevant chunks then the LLM generates a grounded answer from them".split()

def chunk(words, size, overlap):
    step = size - overlap
    return [" ".join(words[i:i+size]) for i in range(0, len(words), step) if words[i:i+size]]

for size, overlap in [(4, 0), (6, 2)]:
    cs = chunk(doc, size, overlap)
    print(f"size={size} overlap={overlap}: {len(cs)} chunks")
    for c in cs:
        print(f"  | {c}")

Overlap helps when a sentence or idea crosses a boundary, but it increases embedding work and can produce duplicate results. A naïve implementation can also create a useless tiny tail; production chunkers usually merge that tail into the previous chunk or apply a minimum-size rule.

Tokens are not words. A tokenizer may represent a common word as one token and a technical identifier as several. Choose sizes in the units your embedding model receives, and check its input limit: an API may truncate an oversized chunk or reject it.

Here is the arithmetic for a 1,000-token section, chunks of 240 tokens, and 40 tokens of overlap. The step is 200 tokens, so chunks begin at positions 0, 200, 400, 600, and 800. That produces five chunks:

  • four full chunks of 240 tokens: 960 tokens
  • one final chunk of 200 tokens: 200 tokens
  • total processed text: 1,160 tokens

The original had 1,000 tokens. Overlap caused 160 token positions to be processed again, a 16 percent increase. Those repeated tokens cost embedding work and storage. They can also cause the retriever to return several nearly identical chunks for one fact, leaving less room for other evidence.

Overlap is insurance, not magic.

A useful starting point is modest overlap, perhaps 10 to 20 percent of the chunk size, but test it against real questions. Self-contained FAQ answers may need none; policies with qualifications split across sentences may benefit from it.

Three ways to split one documenttoo bigsignal dilutedtoo smallcontext gets lostoverlapedges repeat context
Large chunks bury the signal, tiny chunks discard meaning, and moderate overlap protects ordinary boundaries.

Strategies, from simple to structure-aware

Fixed-size chunking splits every document into the same token window. It is fast, deterministic, and an excellent baseline, but it knows nothing about sentences, headings, code, or tables.

Sentence- or paragraph-aware chunking adds text until the next sentence or paragraph would exceed the target size. It avoids many mid-sentence cuts, though a paragraph may still contain unrelated ideas. Keep a maximum and a fallback for unusually large paragraphs.

Structure-aware chunking follows the document hierarchy. Keep a Markdown heading with its section, code blocks intact, table headers with rows, and page or subsection identifiers as metadata. This is usually the strongest first choice for documentation, policies, API references, and well-formed Markdown.

Preserve structure in the chunk text, not only in metadata. Contractor purchases > Refunds gives both the embedder and answer model more scope than a chunk beginning with Refunds.

Semantic chunking detects topic changes, often by embedding consecutive sentences and splitting when similarity drops sharply. It can help badly formatted prose, but adds ingestion work and requires corpus-specific thresholds. A topic shift in a policy may be a crucial qualification rather than a safe split.

Parent-document retrieval separates matching size from answer size. Index a small child, such as a paragraph, for precise matching. When it wins, return a bounded parent, such as the complete subsection or page, to the LLM. The child finds the needle; the parent supplies the surrounding thread.

Do not make the parent a 6,000-token chapter and recreate whole-document retrieval. Keep it bounded, retain the matching child as an anchor, and deduplicate when several children point to the same parent.

Corpus and query patternSensible starting pointMain risk
Self-contained FAQ answersOne answer per chunk, little or no overlapSplitting creates fragments
API documentation and codeHeading-aware chunks with intact examples and error blocksCut examples become meaningless
Policies, contracts, and tablesSection- or row-aware chunks with headings and column names; consider child plus parent retrievalScope, exceptions, units, or headers get separated
Long interviews or narrative proseParagraph-aware chunks, then test semantic boundariesSpeaker and topic changes are unclear

The right granularity follows the structure of the corpus and the questions. “What status code means throttled?” may need an error block; “What is our incident response process?” may need a whole section.

A production pattern

A reliable ingestion pipeline does more than call split(text, 500).

Parse sources while preserving titles, heading paths, code fences, lists, table boundaries, pages, and offsets. Normalize repeated whitespace without erasing labels that explain scope. Start with structure-aware splitting for clean documentation, or paragraph-aware splitting with a maximum for messy text. Add overlap only where a boundary can plausibly divide a thought.

Attach metadata to every child chunk: document ID, version, source URL, page or section, heading path, access-control scope, and character or token offsets. This supports filtering, citations, stale-version cleanup, and debugging. For parent retrieval, store an explicit parent ID; retrieve children, optionally rerank them, group hits by parent, and add only the best few bounded parents to context.

Evaluate chunking with real questions whose correct source sections are labeled. Measure retrieval recall at k, or how often the correct source appears among the first k results. Inspect the final answer too: was the relevant qualification present, and was the right version cited?

Suppose 100 questions produce recall at 5 of 68 percent with fixed 500-token chunks. A structure-aware version reaches 84 percent, but answer accuracy rises only from 72 to 75 percent. Retrieval improved, yet parent context may still be too large, or reranking and answer constraints may be the remaining problems. RAG evals help separate those causes.

Failure modes you can see in production

A high-scoring result produces a confidently incomplete answer. Inspect the chunk, not just its similarity score. If it contains the rule but not its heading, exception, unit, or definition, change the boundary, repeat the section path, or retrieve a bounded parent.

The context window fills with near-duplicates. Excessive overlap or parent expansion may make several hits point to the same text. Count unique parents, reduce overlap, and deduplicate before generation.

Table questions produce fluent nonsense. Values were probably separated from column names or units. Keep headers with rows and test questions that require comparing rows.

Code answers are broken. Do not split code by ordinary sentence rules. Keep functions, request examples, and response objects intact where possible; for large files, split at functions or classes and retain file and symbol metadata.

Also track versions. Delete or deactivate old children atomically so stale parents and current children cannot be retrieved together.

Chunking is worth avoiding when source units are already self-contained: an 80-token FAQ answer, a database row with its schema, or a short product specification may worsen when split. Semantic chunking is also a poor first move when deterministic rebuilds, simple debugging, or ingestion cost matter more than gains on messy text.

Long-context models change the economics, not the logic. A larger parent may fit, but it still costs tokens, can bury evidence among distractions, and cannot restore text absent from retrieval.

In one breath

  • A chunk is the unit your retriever embeds and ranks. Its boundaries determine both what can match a question and what context reaches the LLM.
  • Large chunks dilute retrieval signals; tiny chunks can omit headings, definitions, units, or exceptions.
  • Overlap protects against ordinary boundary cuts, but increases index work and cannot restore missing context.
  • Start with structure-aware or paragraph-aware splitting. Use semantic chunking when messy sources justify its extra ingestion work.
  • Parent-document retrieval uses small children for matching and bounded parents for context. Deduplicate parents.
  • Preserve structure, metadata, versions, and access scope. Measure retrieval recall and final answer quality on real questions.

Quick check

Quick check

0/3
Q1Why can a better embedding model fail to fix bad chunking?
Q2What does overlap accomplish, and what does it cost?
Q3A 4,000-token compliance section contains a 30-token exception under a heading, and users ask questions about that exception. Which design is the strongest starting point?

Next

Chunks become vectors via sentence embeddings stored in a vector database. The full retrieval pipeline is covered in RAG basics and advanced RAG, while RAG evals show how to tune chunking without guessing.

Sign in to track your progress

Completed lessons, your XP, level, and streak save to your account — it's free and takes a few seconds.

Practice this in an interview

All questions
What are chunking strategies in RAG, and how do you choose chunk size?

Chunking divides source documents into retrievable units. Fixed, overlapping, structure-aware, semantic, and parent-child strategies trade retrieval precision against context, duplication, latency, and cost; choose among them using document structure, query granularity, token limits, and an evaluation set rather than a universal token count.

What chunking strategies exist for RAG and how do you choose between them?

Chunking splits source documents into retrievable units before embedding. The right strategy depends on document structure, query style, and the model's context window. Fixed-size chunks are simple but break mid-sentence; semantic or structural chunking preserves coherence; hierarchical chunking enables parent-document retrieval for richer context.

What is Retrieval-Augmented Generation (RAG) and how does a basic RAG pipeline work?

RAG retrieves relevant external documents at query time and gives them to an LLM as context before generation. A basic pipeline ingests and chunks documents, embeds the chunks into a searchable store, retrieves the best matches for a question, and asks the LLM to answer from that evidence.

What is Retrieval-Augmented Generation (RAG) and why is it used?

RAG couples a retrieval step — fetching relevant documents from an external store — with a generative model so the LLM can answer questions about knowledge it was never trained on. It solves the stale-knowledge and hallucination problems without retraining. The pattern is preferred when the knowledge base changes frequently or contains proprietary data.

Related lessons

Explore further