Core Concepts 6 min read Updated Sep 14, 2026

Chunking Strategies That Actually Matter

If a RAG system is giving bad answers, chunking is the first place to look - more often than the embedding model, the vector database, or the LLM itself. A chunk is the unit your system retrieves and hands to the model, so if the boundaries are wrong, everything downstream inherits that mistake.

Fixed-size chunking: simple, and often good enough

The most basic approach: cut the text every N characters (or tokens), full stop, no regard for what's actually at that boundary. It's trivial to implement and completely predictable in size, which matters for cost and latency. Its weakness is exactly what you'd expect - it will happily slice a sentence, a table row, or a code block in half, because it has no idea those things exist.

Recursive chunking: the practical default

Recursive character splitting tries to respect the document's structure before falling back to a hard cut: split on paragraph breaks first, then sentences, then words, only cutting mid-word as an absolute last resort. This is the default most teams reach for, and for good reason - it's a large quality improvement over fixed-size splitting for almost no extra cost.

# Recursive splitting, framework-agnostic shape
def recursive_split(text, chunk_size=1000, overlap=200):
    separators = ["\n\n", "\n", ". ", " "]  # tried in order
    # Splits on the first separator that produces chunks
    # close to chunk_size; falls back to the next one, and
    # finally to a hard character cut if none fit.
    ...

Semantic chunking: split where the topic actually changes

Semantic chunking goes a step further: instead of splitting on structural markers like paragraph breaks, it embeds sentences and looks for the points where meaning shifts noticeably from one sentence to the next, and splits there. The result is chunks that are more likely to be topically coherent - a chunk about "shipping times" doesn't get contaminated with three unrelated sentences about "payment methods" that happened to sit in the same paragraph. It's more expensive to compute (every sentence gets embedded during chunking, not just during the final chunk) and it's usually only worth the cost once fixed or recursive splitting has visibly hit a ceiling on your specific documents.

StrategyHow it decides where to cutBest for
Fixed-sizeEvery N characters, no exceptionsQuick prototypes, uniform plain text
RecursiveParagraph → sentence → word, in that orderThe default for most real documents
SemanticWhere embedded meaning shifts between sentencesLong, topic-dense documents where recursive still underperforms

Chunk size and overlap: the tradeoff underneath all three

Too big, and retrieval gets noisy: a 3000-character chunk covering four different subtopics means a query about one of them drags the other three along as irrelevant context, diluting what the model actually needs to answer well.
Too small, and chunks lose context: a 100-character chunk that's a lone sentence fragment, cut off mid-idea, often isn't complete enough to be useful even when it's semantically the right match.

Chunk overlap - letting consecutive chunks share a slice of text at the boundary - softens the "cut off mid-idea" problem, so an idea that straddles a chunk boundary still appears intact in at least one of the two chunks. A common starting point is 500-1000 characters per chunk with 10-20% overlap, but treat that as a starting point, not a rule: the right numbers depend heavily on your documents and the kinds of questions people actually ask.

Rule of thumb: start with recursive chunking at roughly 500-1000 characters with 15% overlap. Only reach for semantic chunking, smaller chunks, or a custom splitter once you've actually measured that recursive chunking is underperforming for your documents - covered in the evaluation guide later in this series.

Chunking isn't just text - metadata rides along

Every chunk should carry metadata alongside its text: source document, page number, section heading, last-updated date. This isn't optional polish - it's what lets you show a citation the user can verify, filter retrieval to only recent documents, or exclude an entire outdated file without re-indexing everything else. A RAG system with no metadata is a RAG system that can't tell you where an answer came from.

Next up: where those chunks actually live - Pinecone, Chroma, Weaviate, pgvector, and how to pick.
Share this guide

Was this guide helpful?

Thanks for the feedback!

Want more hands-on AI builds like this?

APA Mastery runs live, practical sessions on working with modern AI tools - not just theory.

See What's On →
← PreviousThe RAG Pipeline