Chunking Strategies for RAG
Before anything can be embedded or retrieved, a document has to be cut into pieces. Where you cut decides how much sense each piece makes on its own.
Overview
Before the details
Every piece of RAG downstream of chunking — embedding, indexing, retrieval, reranking — operates on whatever the chunk boundaries produced. Cut a sentence in half and both halves lose the context that made the original sentence meaningful; the embedding of a fragment is not a fragment of the embedding.
Chunking
Resulting Chunks
—Counts
Chunking: A Practical Guide
The retrieval step can only ever be as good as the pieces it is choosing between.
Fixed-size vs semantic
Fixed-size chunking counts a fixed number of words or tokens and cuts there, with no regard for what is at that position — a heading, mid-word, mid-sentence, anywhere. It is simple, predictable, and blind. Semantic chunking respects natural boundaries — sentences, paragraphs, headings — and only splits at those boundaries, accepting some variation in chunk size in exchange for every chunk being a coherent unit.
Why overlap exists
Even a well-placed boundary loses something: whatever came just before a chunk starts is not in it, even though it might be exactly the context needed to make the chunk's first sentence make sense. Overlap re-includes the last few words of the previous chunk at the start of the next one, at the direct cost of storing and embedding the same words twice.
Why documents have to be split
Three reasons, and they compound.
Embeddings blur when the input is long. A vector representing a 20-page document is an average of everything in it, so it is close to nothing in particular. Retrieval precision collapses.
The context window is finite, and shared with the question and the answer. Ten full documents will not fit.
Precision needs granularity. The user asked one question; the answer is one paragraph. Retrieving the whole document buries it.
So documents are split into chunks, each embedded separately. The chunk becomes the unit of retrieval, and how you choose its boundaries determines the ceiling on the whole system's quality.
The strategies, from crude to careful
| Strategy | Splits on | Quality |
|---|---|---|
| Fixed size | Character or token count | Poor — cuts mid-sentence |
| Recursive | Paragraph, then sentence, then word | Good default |
| Structure-aware | Headings, sections, list items | Better for structured documents |
| Semantic | Where the topic shifts, measured by embedding distance | Best quality, highest cost |
| Sentence windows | One sentence, with neighbours as context | Good precision, needs expansion |
| Parent-child | Retrieve small, return large | Best of both |
Fixed-size splitting at 500 characters cuts sentences in half, separates a heading from its content and splits tables. It is the default in many tutorials and the first thing worth replacing.
Recursive splitting tries separators in order — paragraph break, then newline, then sentence end, then space — taking the largest unit that fits. It respects natural boundaries most of the time and costs nothing extra. This is the sensible default.
Structure-aware splitting uses the document's own markup: Markdown headings, HTML sections, PDF outline. A chunk is then a semantically coherent unit by construction, and the heading path can be prepended to give the chunk context ("Handbook > Leave > Parental leave").
Semantic chunking embeds each sentence and splits where consecutive sentences become dissimilar. It finds real topic boundaries and costs an embedding call per sentence at indexing time.
Size and overlap
Size is a trade-off between context and precision:
| Chunk size | Effect |
|---|---|
| 100 tokens | Precise retrieval, often missing context |
| 200–500 tokens | The usual sweet spot |
| 1,000+ tokens | Good context, blurred embeddings, fills the prompt |
Overlap of 10–20% means consecutive chunks share their boundary text, so a sentence spanning a split appears whole in at least one chunk. The cost is duplicated storage and occasionally two near-identical chunks in the results, which reranking or maximal marginal relevance handles.
The number that matters is not the token count in isolation but whether a chunk can answer a question on its own. A chunk beginning "This means that the limit is 30 days" is useless without knowing what "this" refers to — which is the argument for prepending the heading path, or for the parent-child pattern.
Cutting documents up without cutting answers in half
Chunking decides what a retriever can ever return, and the default of a fixed character count fails in a specific way. This measures four strategies against the same document, and scores them on the only thing that matters -- whether a complete answer survives in one piece.
Experiments to try
- Start at 30 words, fixed-size. Several chunks end mid-sentence — the cut counter is not zero.
- Switch to semantic. The cut counter drops to zero at any size — chunks vary a little in length but every one ends on a real sentence boundary.
- Shrink fixed-size chunks to 15 words. More chunks, and more of them are mid-sentence cuts — small fixed windows are the worst case for this failure.
- Add overlap. The highlighted words at the start of each chunk (after the first) are the ones repeated from the end of the previous chunk — visible context carried across the boundary, at the cost of storing it twice.
The short of it
Fixed-size chunking is simple and fast but blind to meaning, and will cut sentences in half whenever the count lands mid-sentence. Semantic chunking respects real boundaries at the cost of variable chunk sizes. Overlap recovers some of the context lost at any boundary by duplicating a small window of text between neighbouring chunks. None of this is free — every choice trades simplicity, storage, or coherence against the others, and the right trade depends on how structured the source documents already are.
Parent-child, and sentence windows
Two patterns resolve the size trade-off rather than compromising on it.
Parent-child (small-to-big). Index small chunks for precise matching, but return their larger parent section to the model. Retrieval operates on 100-token units; generation sees the 800-token section they came from. You get the precision of small chunks and the context of large ones.
Sentence windows. Index each sentence individually, and at retrieval time expand to include the two or three sentences either side. Same idea, finer granularity.
Both require storing the relationship between the indexed unit and its context, which every serious vector store supports through metadata.
What to store alongside the vector
Metadata is what makes a retrieval system usable in production, and it is easy to under-invest in at indexing time:
- Source — document id, title, URL. Needed for citations.
- Location — page number, section heading, character offsets.
- Heading path — prepend it to the chunk text as well as storing it.
- Dates — created and modified, so stale content can be filtered or down-weighted.
- Access control — the groups permitted to see it, filtered at query time.
- Document type — so a query about policy can be restricted to policy documents.
Adding metadata after the fact means re-indexing. Deciding it up front costs nothing.
Document types that need special handling
Tables. Splitting a table mid-row destroys it. Extract tables separately, keep each whole, and store a text summary alongside for embedding.
Code. Split on function and class boundaries, not line counts. A half-function is not retrievable knowledge.
PDFs. Multi-column layouts are frequently extracted in the wrong reading order. Check the extracted text before indexing thousands of documents; a layout-aware extractor is worth the effort.
Transcripts. Split on speaker turns or topic shifts, and keep timestamps in the metadata.
Slides. One slide per chunk usually works, with the deck title prepended.
Questions people ask
What chunk size should I use? Start at 300–500 tokens with 15% overlap and recursive splitting, then evaluate against your own question set.
Is semantic chunking worth the cost? Often yes for heterogeneous documents, and the gain over structure-aware chunking on well-structured documents is usually small.
Should chunks overlap? Yes, 10–20%. It is cheap insurance against boundary loss.
How do I keep context in small chunks? Prepend the heading path, or use parent-child retrieval.
Can chunk size differ within one index? Yes, and it is often sensible — a table or a code function is one chunk whatever its length.
How do I know my chunking is bad? Low recall@k on questions whose answers you know are in the corpus. Then read the retrieved chunks: fragments and mid-sentence cuts are the diagnosis.
Recap in one screen
- Chunks are the unit of retrieval, so their boundaries set the ceiling on system quality.
- Recursive splitting on natural separators is the sensible default; structure-aware is better where structure exists.
- 200–500 tokens with 10–20% overlap covers most cases.
- The real test is whether a chunk can answer a question alone — hence heading paths and parent-child retrieval.
- Store source, location, dates and permissions at indexing time; adding them later means re-indexing.