Skip to main content

Confirm

Are you sure?

Glossary

Chunking

How you cut a page up decides which parts of it a model ever sees.

By · Last updated: September 2026

TL;DR

Chunking is splitting a long document into smaller pieces — chunks — so each can be embedded, stored in a vector index and retrieved on its own. In retrieval-augmented generation, only the chunks relevant to a question go into the prompt, so how you split decides what the model gets to see.

Free plan, no credit card. 1,000 credits a month.

How it works

The strategies

StrategySplitsTrade-off
Fixed sizeEvery N tokens, often with overlapSimple; cuts through sentences and sections
RecursiveOn paragraphs, then sentences, then words, until under NGood default for plain text
Structure-awareOn headings, keeping each section wholeChunks match the author's topics; sizes vary
SemanticWhere embedding similarity between sentences dropsAdapts to content; costs embedding calls

Overlap — repeating the last sentences of one chunk at the start of the next — keeps an answer that straddles a boundary retrievable from either side, at the cost of storing some text twice.

In practice

Chunking a web page

A web page already has the best boundaries: its headings. Convert it to Markdown and split on #, ## and ###, carry the heading path into each chunk so it keeps its context, and fall back to a size split only for sections that are too long:

Split a page by heading
import re, requests

md = requests.post(
    "https://urlpipe.dev/markdown",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"url": "https://example.com/docs/setup", "sync": True},
).text

chunks, path = [], []
for section in re.split(r"(?m)^(?=#{1,3} )", md):
    if m := re.match(r"(#{1,3}) (.+)", section):
        level = len(m.group(1))
        path = path[: level - 1] + [m.group(2).strip()]
    if section.strip():
        chunks.append({"heading": " > ".join(path), "text": section.strip()})

Chunks from raw HTML, or from text with the headings flattened away, lose that structure — and chunks full of navigation text match every query a little and none of them well.

URLpipe

URLpipe's part

URLpipe does not chunk or embed; it gives you the input that chunks well. /markdown returns the rendered page's main content with its headings, lists and tables intact and links absolute, deterministically, so re-fetching an unchanged page yields identical chunks and your index doesn't churn.

Pair it with max_age when you refresh an index: a page re-fetched inside your freshness window is a free cache hit, and comparing the new Markdown with the old tells you which pages actually changed and need re-chunking.

FAQ

Frequently asked questions

What is a good chunk size for RAG?
There is no universal answer; a few hundred tokens per chunk is a common starting point. Test retrieval quality on your own questions and adjust.
Should chunks overlap?
A small overlap helps with fixed-size splits, where boundaries fall mid-thought. With heading-based chunks it matters less, because boundaries follow the content.
Why chunk by heading?
Headings are where the author changed topic, so each chunk is about one thing. That makes its embedding more specific and its retrieval more accurate.

See it on your own pages.

Free plan, no card. Confirm your email and your API key is live — you'll be making real requests in minutes.