datarekha

Chunking for RAG

RAG retrieves chunks — but where do chunks come from? You have to split documents first, and how you split is one of the highest-leverage decisions in a RAG system. Too big dilutes relevance, too small loses context. The strategies, the size-and-overlap trade-off, and why chunking is the unglamorous lever that quietly makes or breaks retrieval.

7 min read Intermediate Generative AI Lesson 20 of 63

What you'll learn

  • Why chunking exists and why it's a high-leverage RAG decision
  • The chunk-size trade-off — dilution vs lost context
  • Chunking strategies — fixed, overlap, sentence/semantic, structure-aware
  • Parent-document retrieval and matching chunks to your queries

Before you start

RAG retrieves “chunks” — but a document isn’t born as chunks. Before anything can be embedded and indexed, you have to split documents into pieces, and how you split is one of the highest-leverage, most underrated decisions in a RAG system. Get it wrong and even a great embedding model retrieves the wrong thing.

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.

The chunk-size trade-off

Everything hinges on one tension:

  • Chunks too big — the one relevant sentence is diluted by surrounding irrelevant text, so its embedding is a muddy average and retrieval precision drops (and you waste context-window space feeding the model padding).
  • Chunks too small — a chunk loses the context needed to understand or answer (a pronoun whose antecedent is in the previous sentence, a number whose units are in the heading), so even a correct retrieval is useless.

The basic mechanics are a window size and an overlap that carries context across boundaries:

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}")
size=4 overlap=0: 4 chunks
  | RAG retrieves relevant chunks
  | then the LLM generates
  | a grounded answer from
  | them
size=6 overlap=2: 4 chunks
  | RAG retrieves relevant chunks then the
  | then the LLM generates a grounded
  | a grounded answer from them
  | them

With no overlap, “generates a grounded answer” is split across two chunks — neither alone says what’s generated. The overlap=2 version repeats “then the” / “a grounded” across boundaries, so a sentence straddling a cut still lands intact in some chunk. Overlap is cheap insurance against splitting a thought in half.

Same document, three ways to chunk ittoo bigrelevant bit diluted in a big chunktoo smalleach piece too small to carry contextoverlapoverlapping edges keep straddling thoughts whole
Too big dilutes the signal; too small strips context; overlapping mid-size chunks balance both.

Strategies, from naive to smart

  • Fixed-size — split every N tokens. Simple and fast, but blindly cuts mid-sentence; almost always paired with overlap.
  • Sentence / paragraph-aware — split on natural boundaries so chunks are coherent units.
  • Structure-aware — respect the document’s own structure: Markdown headings, sections, code blocks, table rows. Keeps semantically-whole units together.
  • Semantic chunking — split where the topic shifts (detect drops in sentence-to-sentence similarity), so each chunk is about one thing.
  • Parent-document retrieval — index small chunks for precise matching, but return the larger parent (section/page) to the LLM, getting precision and context.

In one breath

  • Chunking splits documents before embedding/indexing, and how you split is a top RAG-quality lever — a great embedder can’t fix bad chunks.
  • The size trade-off: too big dilutes the relevant sentence (muddy embedding, wasted context); too small strips the context a chunk needs to be understood.
  • Overlap carries context across boundaries so a thought split by a cut still lands whole in some chunk (the demo: overlap repeats then the across the seam).
  • Strategies: fixed-size + overlap, sentence/paragraph, structure-aware (headings/code), semantic (split on topic shift), and parent-document (index small, return the parent).
  • There’s no universal best — match chunking to your documents and queries, attach metadata, and measure it with RAG evals rather than guessing.

Quick check

Quick check

0/4
Q1Why is chunk size a high-leverage RAG decision?
Q2What does chunk overlap accomplish?
Q3What is parent-document retrieval?
Q4Why is there no universal best chunking strategy?

Next

Chunks become vectors via sentence embeddings stored in a vector database; the retrieval pipeline is RAG basics and advanced RAG, and you tune chunking by measuring with RAG evals.

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.

Related lessons

Explore further

Skip to content