How to Chunk Long Scanned PDFs for Reliable LLM Data Extraction
You have a 900 page scanned statement run, or a stack of remittance advices, and the whole thing does not fit in one API call. So you split it. Then you notice the output has line items that stop halfway, totals attached to the wrong account, and a few rows that appear twice with slightly different spelling. The extraction prompt is fine. The chunking is what broke.
Short Answer
Do not chunk on page counts or token counts. Run a cheap first pass that labels where each record starts and ends, then cut the document only at record boundaries. Overlap each chunk by one page on each side, tell the model to flag partial records at the chunk edges, and remove the duplicates that overlap creates by matching on a normalized record identity key such as invoice number plus line number, not on the extracted text itself.
Chunking Strategies Compared
| Strategy | How it splits | What breaks | Use when |
|---|---|---|---|
| Whole document, one call | No split | Hits page and payload limits, and accuracy drifts on long inputs | Under roughly 30 to 50 pages, clean scans |
| Fixed token count | Cuts at N tokens of OCR text | Cuts mid-table and mid-row constantly, worst option for scans | Retrieval and search, not structured extraction |
| One page per call | Every page is a chunk | Line items and headers that continue across pages | Each page is a self-contained record, like a one page invoice |
| Fixed page window | Every 10 or 20 pages | Cuts records at the window edge, silently | Nothing structured, this is the default that causes the bug |
| Record-boundary chunks with overlap | Cuts only between records, one page overlap | Creates duplicates on purpose, which you then dedupe | Multi-page records, long table runs, statement batches |
| Two pass: locate then extract | Pass 1 maps record spans, pass 2 extracts each span | Costs an extra cheap pass over every page | Large runs where a wrong split is expensive to catch later |
Have a messy PDF? Upload 1-3 sample pages and we will tell you if it is clean, OCR-heavy, or needs human QA.
Why Page Boundaries Break Records
A scanned business document is rarely one record per page. The failure modes are consistent across document types.
Line item tables continue. An invoice with 40 line items runs onto page two, and page two has no header row, no invoice number, and no vendor name. Extract that page alone and the model has 18 orphan rows with nothing to attach them to. It will often invent a plausible parent, because you asked for structured output and it wants to give you some.
Column headers appear once. The column labeled "Qty" sits on page one. On page three the model sees four unlabeled numeric columns and has to guess which is quantity, which is unit price, and which is line total. Guesses here are quiet, not loud.
Totals live at the end. Freight, tax, discounts, and the grand total sit on the last page of the record. If that page lands in the next chunk, the record you extracted does not reconcile and the totals have no parent. Statements are worse, because a running balance carried forward is context the second chunk never sees.
Fixed token chunking makes all of this worse on scans, because OCR text order does not reliably follow reading order. A token boundary can land in the middle of a table cell.
Find the Record Boundary Before You Chunk
The fix is a cheap classification pass before the expensive extraction pass. Send each page on its own to a small model and ask four questions:
- Does this page start a new record? Look for a document number, an issue date, a vendor block, or an account header.
- Does it continue a table from the previous page? Look for a table starting at the top with no header row.
- Does it close a record? Look for subtotal, tax, total, or a signature block.
- What record identifier is visible on this page, if any?
Two structural signals do most of the work and cost nothing to check: the "Page 3 of 7" marker printed by the originating system, which gives you exact record spans when it exists, and the document number repeated in a header or footer, which many accounting systems print on every continuation page.
The output is a page map. Record A covers pages 1 to 4, record B covers page 5, record C covers pages 6 to 19. You chunk on that map. A chunk is one record, or several small records, never a fraction of one.
Overlap Rules That Work on Scans
Measure overlap in pages, not tokens. A partial page is not a useful unit when the model is reading a page image. One page on each side is usually enough, and the purpose is to let the model see that a table started before the chunk began and continued after it ended.
Better than raw overlap is a carried context header. Instead of resending the whole previous page, prepend a short text block to each chunk: the record identifier, the vendor or account name, the column header row, and the last row extracted from the previous chunk. That gives the model its anchors at a fraction of the cost of an extra page image.
Then make partial records explicit. Add a field to your output schema, something like is_partial with values start, end, and complete, and instruct the model to mark any record cut off by a chunk edge. A flagged partial is a record you can stitch. An unflagged truncation is silent data loss.
Dedupe on Record Identity, Not on Text
Overlap creates duplicates by design. The mistake is removing them with a hash of the extracted text, because the same row read twice from two page images will not produce identical text. OCR will disagree with itself on a smudged digit, a currency symbol, or trailing whitespace, and your hash based dedupe will keep both copies.
Key on record identity instead. Build a composite key from the fields that identify the record in the source system: invoice number plus line number for line items, account number plus posting date plus amount plus a normalized description for bank statements, payment reference plus invoice reference for remittance detail. Normalize before comparing. Strip whitespace, uppercase, remove punctuation, round amounts to two decimals, and fuzzy match the description rather than requiring an exact string, because description is the field OCR damages most.
When two copies of a key collide, do not pick at random. Prefer the copy marked complete over one marked start or end. If both are complete, prefer the one from the chunk where the record sits away from the edge.
Finish with a reconciliation check, the cheapest way to catch what dedupe missed. Sum the line items per record against the extracted total. Compare your record count against any count printed in the document. Confirm every source page appears in at least one extracted record, because a page appearing in zero records is a chunk boundary bug.
The Limits That Force Chunking in the First Place
The actual ceilings are higher than most pipelines assume. Anthropic's PDF support documentation puts the maximum at 600 pages per request, dropping to 100 pages when the context window is under 1M tokens, inside a 32MB payload. Each page is processed as both extracted text and an image, with text alone running roughly 1,500 to 3,000 tokens per page depending on density. The docs warn that dense PDFs can fill the context window before reaching the page limit, and recommend splitting into sections. Google's Gemini document processing docs list a 1,000 page maximum, a 50MB file size limit, and 258 tokens per page as an image.
A 900 page scan is not one call in either case. A 40 page invoice batch might be, and forcing that through a chunker adds duplicate risk for no benefit. Chunk because the document exceeds the limit or because accuracy degrades on long inputs, not out of habit.
When You Should Not Build This
If every record fits on one page, skip all of this and process page by page. The complexity here exists to solve multi-page records.
If you have a few hundred pages one time, a commercial OCR product with table detection plus a human checking the output will beat a pipeline you wrote this week. The chunking work pays off on recurring volume.
If your PDFs have a real text layer and a stable layout from one or two sources, a template based parser is cheaper and deterministic. Bring in LLM chunking when layouts vary and the scans are genuinely scans.
DataConvertPro is a managed service. Our team runs this process, checks the reconciliation output, and delivers the Excel or CSV. If you would rather own the pipeline, the recipe above is what we would build.
Frequently Asked Questions
How much overlap should I use between chunks?
One page on each side for scanned documents. More overlap costs tokens linearly and does not improve edge accuracy much past a single page, since the model mainly needs to see that the table started earlier. For long table runs, put the effort into a carried context header rather than into more overlapping pages.
Can I use a model with a very large context window and skip chunking?
Sometimes, and it is worth testing on your own documents. But long inputs of near identical pages, which is exactly what a statement run looks like, are the conditions where models are most prone to blur one record into the next. Chunking also gives you a per chunk retry, so one bad page does not force you to rerun 900.
What if the scan has no page numbers and no repeated document number?
Fall back to visual signals in the classification pass: a new letterhead block, a new date and address block, a table that begins with a header row, or a totals block that closes a record. Where the signals are ambiguous, err toward larger chunks that keep whole records together and let the dedupe pass clean up the extra overlap.
Why does my dedupe keep leaving near duplicate rows?
Almost always because you are comparing raw extracted strings, and two reads of the same scanned row will differ on a character. Normalize case, whitespace, and punctuation, round amounts, then compare identifier fields with fuzzy matching on the description. If duplicates still survive, the identifier you chose is not unique in the source data and the key needs another field.
Ready to Convert Your Documents?
Stop wasting time on manual PDF to Excel conversions. Get a free quote and learn how DataConvertPro can handle your document processing needs with AI-assisted extraction and human verification.