LLM applications and RAG

Chunking Strategies That Change Your Answers

How you split documents sets the ceiling on everything downstream. The five splitting methods, what each one destroys, the contract every chunk should satisfy, and how to test a change without fooling yourself.

On this page
  1. Chunking sets the ceiling on everything downstream
  2. The five splitting methods and what each one destroys
  3. The Chunk Contract: four clauses every chunk should satisfy
  4. Overlap is insurance, not a strategy
  5. Index small, send big
  6. Tables, code and the documents that break every splitter
  7. Sizing your corpus, with the arithmetic exposed
  8. How to test a chunking change without fooling yourself
  9. A default worth starting from

Chunking sets the ceiling on everything downstream

The short answer

A chunk is the smallest unit your system can retrieve and the smallest unit it can cite, so the split decides which facts are reachable at all. Cut a claim away from the heading that scoped it and the fact is still in your corpus and permanently unreachable, no matter how good your embedding model, your reranker or your prompt is. Chunking is the only stage in a RAG pipeline whose mistakes cannot be repaired further down.

  • One claim per chunkA chunk holding two unrelated claims retrieves for both and answers neither cleanly. A chunk holding half a claim answers nothing.
  • Structure beats sizeSplitting on document structure preserves what a fixed character count destroys. Token count is a cap, not a strategy.
  • Index small, send bigRetrieve precise units and expand to the surrounding section at assembly time. Precision and context are not the same trade-off.
  • Every change is a re-indexAltering the splitter means re-embedding everything and recalibrating every score threshold you tuned. Budget the change, do not experiment casually in production.
The vocabulary, defined tightly
Chunk
A passage of source text stored and indexed as a single retrievable unit, carrying its own identifier and metadata so it can be found, ranked and cited on its own.
Overlap
A number of tokens repeated at the boundary between neighbouring chunks, so a claim sitting across a cut still appears whole in at least one of them.
Parent-child retrieval
A pattern where small chunks are indexed and searched for precision, but the larger section containing the winning chunk is what gets sent to the model.
Contextual header
A short generated preamble attached to a chunk before embedding, naming the document, the heading trail and the situation the passage refers to, so the chunk reads correctly in isolation.
Late chunking
Embedding a long passage first so every token sees the full context, then pooling the token vectors into chunk vectors afterwards, rather than embedding each chunk in isolation.

The five splitting methods and what each one destroys

There are five methods in real use and they form a ladder of cost against fidelity. Most teams should start at structure-aware, not at fixed-size, because the extra day of work removes the largest category of unreachable facts.

MethodHow it cutsWhat it destroysUse it when
Fixed sizeEvery N tokens, ignoring the text entirelySentences, claims, table rows, the heading that scoped the passageThe corpus is unstructured plain text and you need a baseline today
Recursive characterTries paragraph breaks, then sentence breaks, then characters, until the piece fitsLess than fixed size, but still cuts blindly once a section exceeds the capYou need a sane default across mixed formats with no parsing effort
Structure awareOn real document structure: headings, list items, table boundaries, code blocksVery little, provided the parser preserved the structure in the first placeThe corpus has structure, which covers most documentation, policies and contracts
SemanticWhere the embedding similarity between consecutive sentences drops below a thresholdNothing obvious, but boundaries move whenever you change the embedding model or the thresholdProse with no headings, such as transcripts, interviews and long-form reports
Late chunkingCuts after embedding, so each chunk vector was computed while the whole document was visibleNothing, but it needs an embedding model with a long input and more compute per documentChunks lose meaning without their surroundings and you can afford the indexing pass
Splitting methods compared by what they preserve and what they cost
Size is a cap, not a strategy

A target of roughly 300 to 500 tokens with a hard ceiling is a reasonable band for documentation and policy text, because it usually holds one complete idea and still leaves room to send several passages. Treat it as a starting point to measure, not a rule. What matters is that the boundary falls on a real edge in the document.

The Chunk Contract: four clauses every chunk should satisfy

Stop asking how big a chunk should be and start asking what a chunk owes the rest of the system. Four obligations cover it, each with a test you can run on a random sample in an hour.

Framework

The Chunk Contract

Sample fifty chunks at random from your index and check each clause by hand. The clause you fail most often tells you exactly which part of the pipeline to fix, and the exercise takes about an hour.

01
Clause 1, Self-sufficient

A colleague reading only this chunk can tell what it is about, who it applies to and when it took effect. Test: cover the document name and read it aloud. If it opens with 'this' or never names the product or the period, it fails. The fix is a contextual header, not a bigger chunk.

02
Clause 2, Single claim

One dominant answerable proposition per chunk. Two unrelated claims means it retrieves for both queries and dilutes its own embedding, since a vector is an average and averaging two topics lands you between them, near neither. Test: list the questions this chunk answers. More than about three and it should be split.

03
Clause 3, Addressable

The chunk carries a stable id, a source path, a version and a character range, so an answer can cite the exact place. Test: take a chunk id from a log entry three weeks old and try to reach the source. If the id was a row number in a table you rebuild nightly, it fails.

04
Clause 4, Reassemblable

The chunk knows its neighbours and its parent section, so retrieval can expand context after ranking. Test: given a chunk id, can you fetch its section in one lookup? If not, every chunk has to be both precise and complete, and nothing is both.

Overlap is insurance, not a strategy

Overlap repeats a slice of text at each boundary so a claim cut in half still appears whole somewhere. It is cheap insurance against the boundary problem and it is not a fix for bad boundaries, because it duplicates content into the index and duplicated content wins twice in the same result list.

Deduplicate before you assemble the prompt

If you use overlap and do not dedupe, your top-k is a lie. Two chunks sharing most of their text both score highly on the same query, so you pay for five passages and send the model two. Compare candidates before assembly, drop any whose text is largely contained in a higher ranked one, and refill from further down. That is twenty lines of code and the highest return change most retrieval stacks are missing.

Index small, send big

Precision and context pull in opposite directions, and you do not have to choose. Index a small unit so the vector is sharp and the match is specific, then expand to the parent section at assembly time so the model has enough surrounding material to reason with. The pattern goes by several names and it is the single biggest quality jump available after hybrid retrieval.

Three ways to expand

  1. Sentence window. Index individual sentences, send the sentence plus a few either side. Best for dense reference material where the answer is one line and the neighbours qualify it.
  2. Parent document. Index paragraph-sized chunks, send the whole section containing the winner. Best for policy and documentation, where the heading and the exceptions matter.
  3. Summary index. Index a generated one-line summary of each section, send the full section. Best for long narrative documents where the literal wording matches nobody's question.

Expansion has a cost people forget: your context grows by the expansion factor, on every question, forever. Index at 150 tokens and send parents of 800 and your input tokens went up more than five times, which appears on the bill rather than in a metric. Cap the expansion and check the arithmetic in RAG explained for builders.

The contextual header, which is cheaper than it looks

Before embedding, prepend a block naming the document, the heading trail, the version and one generated sentence situating the passage. It costs one small call per chunk at ingest, once, and it fixes clause one for the whole corpus. It also improves keyword search, because the product name and version now sit in the chunk text where BM25 can see them.

Chunk enrichment: stored format and the prompt that generates ittext
# 1. The stored chunk format. Everything above the rule is generated
#    at ingest and prepended before embedding, so the chunk reads alone.

{doc_title} > {heading_path}
Version {version}, effective {effective_date}. Applies to: {audience}
Context: {situating_line}
---
{chunk_text}


# 2. The prompt that writes situating_line, one call per chunk at ingest.
#    Keep it short. This is a situating sentence, not a summary.

SYSTEM:
You are given a whole document and one passage from it. Write ONE sentence,
under 30 words, that lets a reader understand the passage without the
document. Resolve pronouns and vague references to their actual subject.
Name the entity, the product, the version and the time period the passage
is about, but only if the document states them. Do not add facts. Do not
summarise the passage. Do not use the words "this passage" or "the document".
If the passage is already self-explanatory, output the single word: NONE.

USER:
<document>{full_document}</document>
<passage>{chunk_text}</passage>

# Worked example
# passage:         "The window is 14 days from the invoice date."
# situating_line:  "Refund window for annual Enterprise plans bought after
#                   the January 2026 pricing change."

Tables, code and the documents that break every splitter

Some content cannot be cut by any general rule and needs a specific one. Tables are the worst offender, because a table split across chunks produces rows that have lost their column headers, and a row of numbers with no headers is worse than nothing. It is confidently retrievable and meaningless.

ContentWhat goes wrong by defaultThe rule that fixes it
TablesRows split away from headers, or the whole table flattened into a run-on lineKeep small tables whole in one chunk. For large ones, serialise each row with its column names repeated, plus a caption chunk describing the table
Code blocksSplit mid-function, so the retrieved fragment does not compile or explain anythingNever split inside a fenced block. If the block exceeds the cap, keep it whole and accept an oversized chunk
Scanned PDFsThe extractor returns nothing or returns page furniture only, and it exits cleanlyDetect empty or near-empty extractions at ingest, route to OCR, and fail the ingest loudly if the page yields no text
Multi-column layoutsText is read across columns, interleaving two unrelated sentences into oneUse a layout-aware extractor and spot-check the output visually. This one is invisible in the logs and obvious to the eye
SpreadsheetsTreated as text, producing thousands of near-identical low-value chunksDo not embed them. Query them. Route numeric and aggregate questions to the data, not the retriever
Content types that need their own rule
Read fifty extracted chunks before you tune anything

Print a random sample of your chunk store and read it. Teams that skip this discover months later that a large slice of the corpus was navigation boilerplate, cookie banners or a repeated legal footer, all of which embed into confident near-duplicate matches for any question. Ingestion problems masquerade as retrieval problems. Extracting data from documents covers the parsing side, and our document processing work exists mostly because this stage is where corpora go wrong.

Sizing your corpus, with the arithmetic exposed

Before choosing a chunk size, run the numbers on your own corpus. The two figures that matter are how many vectors you will store, which drives index cost and query latency, and how many tokens each question will carry, which drives the recurring bill.

Chunk count, index size and context per question

The embedding price is a stand-in so the arithmetic runs, and it is not a quote. Substitute your provider's current figure. Note that halving the chunk size roughly doubles the vector count while leaving the tokens you send per question unchanged, until you start expanding to parents.

0Chunks in the index
0Cost of one full re-embed
0Retrieved tokens per question

How to test a chunking change without fooling yourself

Change one thing, hold everything else frozen, and look at the questions that got worse rather than at the average. Chunking changes almost always improve the mean and almost always break a specific class of question, and the mean will happily hide that from you until a user finds it.

  1. Freeze the retriever, the reranker and the modelnon-negotiable

    Same embedding model, same fusion weights, same top-k, same prompt, same model version. Two changes at once teaches you nothing and buys a week of arguing about which one did it.

  2. Use a question set you did not generatethirty is enough

    Real user questions with hand-labelled correct sources. Model-generated questions about documents the model just read score well under any scheme, because they are phrased in the source's own words, which is exactly the case chunking does not need to handle.

  3. Score recall@5 and recall@20 per question, not just the meankeep the table

    Store the per-question result for both runs side by side. The mean tells you the direction. The per-question table tells you the truth.

  4. Read every question that went from found to missedthe real output

    This list is the actual result of the experiment. It usually clusters: every table lookup broke, or every question about exceptions broke because the exceptions now sit in their own chunk with no heading.

  5. Check the citation surface, not only the hit rateeasily missed

    A smaller chunk can retrieve correctly and still produce a worse answer, because the model receives a fragment without the qualifying sentence. Read ten full answers, not just the retrieval scores.

  6. Price the migration before you committhe part that stalls

    A chunking change means a full re-embed, a re-index and recalibrating every threshold including your abstention floor. Keep the old index until the new one is scored, and never swap the splitter and the embedding model in one release.

A default worth starting from

Here is a configuration that is hard to beat as a starting point for documentation, policies, contracts and knowledge base content. It is not a law and every clause of it should be measured on your own gold set. It exists so you can stop reading and start building today, then improve from a known position instead of from a blank page.

Starting configuration for a text corpus
0 of 10 done

Once the split is right, the next failure to hunt is the one where retrieval works, the correct passage is in context, and the answer is still wrong. That is a different mechanism, covered in why your RAG system gives confident wrong answers.

Questions readers ask next

What is the best chunk size for RAG?
There is no single right number and the question misdirects effort. Roughly 300 to 500 tokens works as a starting point for documentation and policy text because it usually holds one complete idea, but boundary position matters far more than count. Split on real structure such as headings and table edges, use the token figure only as a ceiling, then measure recall at five on your own labelled questions.
How much overlap should I use between chunks?
Ten to fifteen percent, and only where you had to force-split a section that exceeded your ceiling, since structural boundaries already fall on a real edge. Whatever you choose, deduplicate the result list before assembling the prompt, because overlapping chunks share text, both score highly on the same query, and you end up paying for five passages while sending two distinct ones.
Is semantic chunking better than fixed size chunking?
It is better on unstructured prose such as transcripts and interviews, where there are no headings to split on. On documents that have structure, splitting on that structure beats it and costs less. Semantic boundaries also depend on the embedding model and a threshold, so they move when you change either, which makes results harder to reproduce and regressions harder to explain.
Should I re-chunk my whole corpus if I change the strategy?
Yes, and treat it as a migration rather than a config change. Mixed chunk sizes in one index produce inconsistent similarity scores, so ranking becomes unstable. A change means re-embedding everything, rebuilding the index and re-deriving any threshold used for abstention, since those were tuned against the old distribution. Keep the old index until the new one has been scored on the same questions.
How do I stop tables being destroyed during chunking?
Detect them at parse time and give them their own rule. Keep small tables whole in one chunk so headers stay with rows. For large tables, serialise each row with its column names repeated inline, and add a caption chunk describing what the table contains. If the real questions are about counting or comparing rows, do not embed the table at all, query the underlying data.
What is parent-child retrieval and when should I use it?
You index small chunks so vectors are sharp and matches are precise, then send the larger section containing the winning chunk so the model has enough context to reason with. Use it wherever a precise match alone would mislead, which covers most policy and documentation content where exceptions and scope live in surrounding sentences. Cap the expansion, because context tokens are charged on every question.
Cite this

ChatGPTalker. "Chunking Strategies That Change Your Answers." chatgptalker.com, 2026-08-26. https://chatgptalker.com/guides/chunking-strategies/

Rather have it built than read about it?

Send the process you want automated. You get a scoped plan back, with the build shape, the stack and a realistic timeline.

Start a project