The only formulas you need, restated so this page stands alone:
Relevant background: Retrieval-Augmented Generation (RAG), Text Embeddings and Cosine Similarity, Vector Databases and ANN Search, Context Window Limits of LLMs, Tokenization, Metadata Filtering in Retrieval.
Answer: the chunk step. A retriever can only return the units you indexed, so if a unit is badly sized (too big = blurry vector, too small = no context) no downstream stage can recover the lost precision or context. Chunking sits at the very front, so its quality is an upper bound on everything after it.
Recall Solution
(a) → chunk too big — one vector must average many ideas, giving semantic blurring.
(b) → chunk too small — the chunk lost its surrounding context, so the embedding is ambiguous.
With no overlap the stride equals c, so use M=⌈N/c⌉.
M=⌈4008000⌉=⌈20⌉=20 chunks.
It divides evenly, so no rounding was needed — but we still write the ceiling out of habit, because most real numbers won't divide cleanly.
Recall Solution
Overlap changes the stride to c−o=400−40=360. Use the overlap formula:
M=⌈c−oN−o⌉=⌈3608000−40⌉=⌈3607960⌉=⌈22.11…⌉=23 chunks.Why more chunks than Q1? Each chunk now advances only 360 new tokens instead of 400, so you need more of them to cover the same document. Overlap costs storage — that's the price of protecting facts near boundaries.
Recall Solution
Use o≥s−1:
o≥14−1=13.
So o=13 is the minimum; a safe practical choice is o≈15–20. Why s−1 and not s? Two neighbouring chunks share o tokens; a window of length up to o+1 that straddles the boundary is fully inside at least one chunk. Setting o+1≥s gives o≥s−1.
Recall Solution
Use P(break)≈cs−1=50014−1=50013=0.026=2.6%.
Small, but over thousands of documents that's many lost facts — which is exactly why overlap exists.
M800=⌈16000/800⌉=20. M400=⌈16000/400⌉=40. Factor =40/20=2×.
This matches M∝1/c: halve c, double the vectors.
Cost: twice the storage and slower nearest-neighbour search in the vector DB.
Benefit: finer resolution — each vector represents one tighter idea, improving precision.
Recall Solution
The fact has span s=4, so it needs o≥s−1=3.
o=1: the shared band is only 1 token wide; the 4-token fact cannot fit entirely inside either chunk → split, not retrievable intact.
o=3: the shared band is 3 tokens; any window of length ≤o+1=4 straddling the boundary fits fully in one chunk → the fact survives in the right-hand chunk (or left, depending on position).
Look at the green band in the figure widening from 1 to 3 — that widening is literally the guarantee.
Recall Solution
Fixed-size cuts land at arbitrary token positions — mid-sentence, mid-table-row, or mid-code-block — producing chunks that are syntactically broken and semantically blurry. Recursive/structure-aware chunking splits on the biggest natural separator first (\n\n, then sentences), and document-structure chunking makes one chunk per section and attaches the heading path as metadata. Both keep each chunk a coherent idea, so embeddings are sharper and retrieval is more precise.
Recall Solution
Benefit: boundaries follow meaning (a genuine topic shift), not an arbitrary token count, so chunks are maximally coherent.
Cost: you must embed every sentence to compute those distances — many extra embedding API calls, so it is slower and more expensive to build the index. See Text Embeddings and Cosine Similarity for the distance measure.
(a) Strategy:Parent-document / small-to-big, layered on document-structure chunking (clauses are natural units).
(b) Index unit: a small precise piece — e.g. the single obligation sentence "Either party may terminate with 30 days' written notice." Small chunk → sharp embedding → nails the nearest-neighbour match.
(c) Return unit: the whole parent clause §7.3 — enough context for the LLM to answer and handle follow-ups without a second query.
(d) Metadata: the clause/section path (e.g. section = "7.3 Termination"), enabling metadata filtering to restrict search to relevant sections.
Why this design: it decouples the retrieval unit (tiny, precise) from the generation unit (large, contextual) — the defining advantage of small-to-big.
Recall Solution
(i) Protect the span: need o≥s−1=29.
(ii) 20% cap:0.20×512=102.4, so any o≤102 is allowed.
A clean choice satisfying both is o=30 (or the tidy o≈50). Take o=30: stride =512−30=482.
M=⌈c−oN−o⌉=⌈48250000−30⌉=⌈48249970⌉=⌈103.67…⌉=104 chunks.Why these steps: the span constraint sets the floor on o; the 20% rule sets the ceiling; picking anything in between and plugging into the stride formula gives the index size.
Let the chunks start at token positions 0,(c−o),2(c−o),…. After M chunks the last chunk ends at position:
c+(M−1)(c−o).
(The first chunk contributes its full length c; every one of the remaining M−1 chunks advances the coverage by one stride c−o.)
We need this to reach or pass the final token N:
c+(M−1)(c−o)≥N.
Isolate M−1: (M−1)(c−o)≥N−c⇒M−1≥c−oN−c.
Add 1: M≥1+c−oN−c=c−o(c−o)+(N−c)=c−oN−o.
Since M must be a whole number and we need the smallest such M, take the ceiling:
M=⌈c−oN−o⌉.■
Recall Solution
(a) o=0:M=⌈(N−0)/(c−0)⌉=⌈N/c⌉ — the no-overlap formula falls straight out. ✓ Consistent.
(b) N≤c: the whole document fits in one chunk. Plug N=c: M=⌈(c−o)/(c−o)⌉=⌈1⌉=1. For N<c the numerator N−o<c−o, so the ratio is <1 and the ceiling is 1. ✓ Exactly one chunk — correct.
(c) o→c: the stride c−o→0+, so M=⌈(N−o)/(c−o)⌉→∞. Interpretation: chunks barely advance, so you need infinitely many to cover the document — the mathematical warning against runaway overlap.
Recall Solution
True token length: 40,000 chars÷4 chars/token=10,000 tokens.
Teammate expected (treating c=1000 as characters): ⌈40000/1000⌉=40 chunks.
Reality (model chunks by tokens, c=1000 tokens): ⌈10000/1000⌉=10 chunks.
The mismatch is a 4× error. Lesson: always chunk on the same tokenizer the model uses — see Tokenization — because "size" means tokens, and ≈4 chars/token holds only for English (code and other languages differ wildly). This also interacts with Context Window Limits of LLMs: mis-sized chunks can silently overflow the window.
Recall Solution
Need M=⌈N/c⌉≤120. The binding condition is N/c≤120 (ceiling only ever rounds up, so satisfying the un-ceiled inequality with a whole-token boundary is enough here). Solve for c:
c≥120N=12060000=500.
Smallest allowed chunk size: c=500 tokens. Check: M=⌈60000/500⌉=⌈120⌉=120≤120. ✓ If you tried c=499, M=⌈60000/499⌉=⌈120.24⌉=121>120 — over budget. So c=500 is exactly on the edge.
Recall Feynman check: say the whole ladder in one breath
Chunking sets the quality ceiling (L1). You size the index with ⌈(N−o)/(c−o)⌉ and protect facts with o≥s−1 (L2). Smaller chunks trade storage for precision, and structure beats blind cuts (L3). Real pipelines decouple a tiny precise index unit from a large contextual return unit (L4). And the formula behaves sensibly at every edge — no overlap, tiny docs, runaway overlap, token-vs-char, and hard budgets — as long as you never drop the ceiling (L5).