Chunking documents so retrieval works
How chunk size, overlap and metadata affect whether the right passage is found.
In a retrieval system, the model never sees your whole knowledge base. It sees a few pieces of it. How you cut documents into pieces, called chunking, quietly decides whether the right passage can be found at all. Many "the AI gave a wrong answer" reports turn out to be chunking problems.
What chunking is for
Two constraints push you to chunk:
- Embedding models and prompts have length limits.
- A single vector for a long document blurs many topics together, so search matches poorly. A vector for one focused passage is sharper.
The goal is chunks that are small enough to be about one thing and large enough to make sense on their own.
Common strategies
| Strategy | How it works | Good for | Watch out for |
|---|---|---|---|
| Fixed size | Every N characters or tokens | Quick baselines | Cuts through sentences and tables |
| Fixed size with overlap | Neighbouring chunks share a margin | Keeping context across boundaries | Duplicate text in results |
| By structure | Split on headings, paragraphs, list items | Manuals, policies, articles | Uneven sizes |
| By meaning | Split where the topic shifts | Long narrative text | More complex, needs tuning |
| Parent and child | Search small chunks, return the larger section around them | Precise search, generous context | Extra bookkeeping |
A sensible default is structure-aware splitting with a size cap and a modest overlap: respect headings and paragraphs, and only fall back to fixed-size cuts inside very long sections.
def chunk_by_paragraph(text, max_chars=1200, overlap=150):
paragraphs = [p.strip() for p in text.split("\n\n") if p.strip()]
chunks, current = [], ""
for p in paragraphs:
if len(current) + len(p) + 2 <= max_chars:
current = f"{current}\n\n{p}" if current else p
else:
if current:
chunks.append(current)
tail = current[-overlap:] if current else ""
current = (tail + "\n\n" + p).strip()
if current:
chunks.append(current)
return chunks
The numbers are starting points, not rules. Measure with your own questions.
Keep the context attached
A chunk that says "It is not refundable after 30 days" is useless if the reader cannot tell what it is. Good pipelines attach context to each chunk:
- The title and section headings above it, prepended to the text or stored as metadata.
- The source, page number and date, so answers can cite and users can verify.
- Permissions or audience labels, so retrieval never returns something the asker should not see.
Special content needs special handling
- Tables. Splitting a table by size destroys it. Keep a table whole where you can, or convert rows into short sentences that repeat the column headers.
- Code. Split on functions or classes, not arbitrary lines.
- Lists and procedures. Keep a numbered procedure in one chunk; half a procedure is dangerous.
- PDF extraction noise. Headers, footers and page numbers repeat on every page and pollute chunks. Strip them.
How to choose sizes
There is no universal best size. Smaller chunks give precise matches but may lack context; larger chunks carry context but dilute the match. The practical method:
- Write 20 to 50 real questions with the passage that answers each.
- Try two or three chunking settings.
- For each, measure how often the correct passage appears in the top few results.
- Choose the setting that wins, and re-check when your documents change type.
Common mistakes
- One giant chunk per document.
- Cutting mid-sentence or mid-table with no overlap.
- Throwing away headings, so chunks lose their meaning.
- Changing chunking without re-running the evaluation.
- Ignoring duplicates: the same paragraph appearing in many chunks crowds out other results.
Try it yourself
Take one real document of a few pages. Chunk it three ways (fixed size, by paragraph, by heading). Write five questions whose answers are in it. For each strategy, check by eye whether the right chunk comes back first for each question. Notice which questions fail and why; the failures teach more than the successes.
Keep learning
How this is used in practice
Typical use cases
- Policy and contract search: split by clause or heading so an answer keeps its context.
- Support tickets: keep the question, steps tried and resolution together.
- Code and docs assistants: chunk by function or section, not by character count.
General examples of where this idea is applied, not tied to a particular company.
Real-world write-ups
Argues that flattening past support tickets into plain text loses structure. Keeps each ticket's sections and links between tickets in a graph and retrieves sub-graphs; reported as deployed in their support team.
2024 · source checked 26 Sep 2026 ↗The paper that named RAG: a language model paired with a searchable passage index so answers can draw on external knowledge.
2020 · source checked 26 Sep 2026 ↗Summaries are ours, in our own words; follow the links for the full detail. Each source was opened and checked on the date shown.
Tools and infrastructure in this guide
Mapped to our tools and tech stack.
Further reading and tools
Official documentation, papers and code referred to in this guide. Links open in a new tab.
More guides
Book a call
Tell us your background and goal — we'll map a course path that fits.
Talk to an advisor