Skip to content
RAG Explained Better

Parsing PDFs for RAG Without Destroying the Document

Layout, columns, headers and footnotes decide what your chunker sees. Parser options compared on the same document set.

PDF parsing for RAG converts a print-oriented PDF into structured text — typed elements, Markdown, or JSON — that a chunker can split without destroying reading order, tables, or section boundaries. A bad parse poisons every embedding that follows: the chunker never sees the original page, only what the parser emitted. This page covers why PDFs break naive extractors, what the chunker inherits, how text-layer / layout / vision parsers differ, and when to escalate to OCR or table extraction. The stage overview lives on document ingestion.

Why is PDF parsing hard for RAG?

PDF parsing is hard for RAG because a PDF stores positioned glyphs on a canvas, not a flowing document tree — reading order, columns, headers, footers, and tables are reconstruction problems, not simple string reads (Firecrawl, “Best PDF Parsers for AI and RAG Workflows,” April 2026; BuildRag, Parsing PDF Documents tutorial; Nanonets, September 2024).

Four failure shapes show up constantly in production corpora:

  • Multi-column reading order. Linear extractors walk the wrong path — down one column, or interleaved across columns — and produce jumbled prose that no chunker can repair (Nanonets’ qualitative PyPDF dumps on a multi-column counsel block in the Allbirds S-1 filing).
  • Headers and footers mixed into body text. Running titles and page numbers land in the extracted stream as if they were content (BuildRag; Kanaka Software PDF preprocessing, March 2025).
  • Scanned or image-only pages. There is no text layer to read; without OCR the page is empty to the pipeline (Codex / Medium production-PDF blueprint, December 2025; superml ingestion tutorial).
  • Tables as linear text. Cell structure collapses into a token soup; numbers lose their headers (Elasticsearch Labs PDF-tables post; Unstructured FAQ on complex tables, May 2025).

A 2024 survey from Peking University and Shanghai AI Lab (arXiv:2410.21169, cited in Firecrawl’s 2026 roundup) draws the line that matters for RAG: basic OCR pulls words; a document parser recovers headings, table grids, and reading order. The same survey flags layout-error cascading — a small layout mistake upstream becomes a severe OCR or element error downstream — which is exactly how a bad parse corrupts a whole section’s worth of retrieved context. Do not trust roundup “failure rate” percentages without your own measurement; treat them as vendor claims until you verify them on your corpus.

What does the PDF parser hand to the chunker?

Whatever the PDF parser emits — flat text, typed elements, or Markdown — is the only document the chunker ever sees; layout mistakes become permanent chunk boundaries and permanent embedding noise.

Production parsers converge on structured intermediates rather than a raw string. Unstructured’s pipeline (Part 1–2, May 2025) emits a list of semantic elements such as Title, NarrativeText, Table, and Image, each carrying metadata (page, coordinates, type). IBM’s Docling builds a DoclingDocument that exports to Markdown, HTML, or JSON with layout, reading order, and table cell boundaries intact (Firecrawl roundup; BuildRag Docling section). LlamaParse and Marker likewise target Markdown as the LLM-ready handoff (KX Systems LlamaParse walkthrough; Firecrawl on Marker-PDF).

That handoff decides retrieval quality before any splitter runs:

  • Column-jumbled text becomes mid-idea chunks that retrieve as nonsense.
  • Headers repeated on every page spam the index with chrome tokens.
  • Footnotes glued to the wrong paragraph attach caveats to the wrong fact.

Document-aware chunking (ShinRAG, PDF ingestion note) only works when structure survived the parse. Once you have clean Markdown or a real heading tree, continue with structure-aware chunking; the strategy catalogue sits on chunking.

How do text extraction, layout detection, and vision models differ?

PDF parsers for RAG fall into three mechanism families that trade speed, cost, and layout fidelity — Unstructured’s Fast / Hi-Res / VLM / Auto strategies and Firecrawl’s text / OCR / neural typology are the same three ideas under different product names.

  1. Text-layer extraction. Reads embedded PDF text operators and applies light heuristics for reading order. Fast and cheap. Fails on scanned pages and often on multi-column layouts. This is the pypdf / PyMuPDF class, and Unstructured’s fast strategy (BuildRag strategy table; Unstructured Part 2, May 2025).
  2. Layout detection plus targeted OCR. An object-detection or layout model proposes regions (titles, paragraphs, tables, figures); OCR runs on those boxes; table models recover grids. Unstructured’s hi_res path uses a YoloX-class detector and a Table Transformer, and typically serializes tables as HTML because HTML keeps merged cells and nested headers that Markdown flattens (Unstructured Part 2). Docling and Marker sit in this family for self-hosted, layout-aware Markdown (Firecrawl; BuildRag).
  3. Vision-language models. The page is treated as an image and prompted into a structure ontology. Unstructured’s VLM strategy routes to models such as GPT-4o-class or Claude 3.7 Sonnet-class APIs (as named in that May 2025 post — verify current model IDs before you pin them). Highest accuracy on damaged or unconventional pages; highest cost and latency; VLMs can hallucinate or misread dense text (Firecrawl citing arXiv:2410.21169; Unstructured’s own hallucination caveat).

Auto / per-page routing (Unstructured Auto; Firecrawl auto mode) analyzes each page and applies the cheap path to simple digital text while escalating complex or scanned pages — the practical default for mixed corpora. Scanned-page OCR depth — engines, error rates, reject-versus-index — belongs on OCR and scanned documents, not here.

Which PDF parser should you use for which document type?

There is no universal best PDF parser for RAG — match the parser class to the document type, then measure on your own corpus. Public roundups disagree, and almost none publish a shared, reproducible same-corpus leaderboard (the gap this site’s map already flags).

Use these qualitative rules drawn from Fast.io’s by-type table (2026), Firecrawl’s honest takes (April 2026), and BuildRag’s Unstructured-versus-Docling comparison — not as scores:

  • Text-heavy digital reports — lightweight text extractors (PyMuPDF4LLM / Marker class) are usually enough and stay fast.
  • Multi-column or mixed-layout digital PDFs — layout-aware parsers (Docling; Unstructured hi_res).
  • Complex tables and charts — vision or table-specialized paths (LlamaParse; Docling; Elastic’s alternate table-parsing approach when tables are the product).
  • Scanned or image-only pages — OCR path; see OCR and scanned documents.
  • Mixed corpora — per-page Auto routing so you do not pay VLM prices for every clean text page.

Deployment splits the field further. Docling and Marker are open-source and self-hosted (model-weight downloads and GPU help throughput; Firecrawl notes ~1–2 GB cold-start weights for Docling depending on config — verify on the project you pin). LlamaParse, Firecrawl’s document API, and Unstructured’s cloud platform are API / pay-per-page — check current pricing as of July 2026; do not invent dollar figures. Limitations are real: Firecrawl notes LlamaParse can interleave multi-column text; Fast.io calls Unstructured table extraction hit-or-miss on hard grids. When a platform lists vector destinations, popular stores include Weaviate, Pinecone, Qdrant and Milvus (Unstructured destinations list, May 2025) — placement is not a quality ranking.

Measure on your corpus — we will not invent a leaderboard

Feature tables are not benchmarks. Run the same document set through two candidate parsers, inspect reading order and table grids by eye, then measure retrieval on the chunks each produces. A percentage that has no named method and no shared corpus is not citable here.

What do headers, footers, and columns do to retrieval?

Repeated headers, footers, and wrong reading order become indexed “content” that dilutes embeddings and retrieves chrome instead of answers — which is why layout, columns, headers, and footnotes decide what your chunker sees.

  • Running headers and page numbers appear in every page’s extract, so every chunk can carry the same boilerplate tokens (BuildRag; Kanaka). Strip them after parse on document cleaning.
  • Multi-column pages cause extractors to read down a single column or to interleave columns into one stream. Nanonets’ side-by-side PyPDF1 / PyPDF2 dumps on an Allbirds S-1 multi-column counsel block show the qualitative failure: words from different columns land adjacent, destroying sentence meaning before chunking starts.
  • Footnotes and sidebars attach to the wrong narrative block when reading order is wrong, so a retrieved chunk carries the wrong caveat next to the wrong claim.

Fix order is parse first (layout-aware when columns exist), then clean chrome, then chunk. “Parse PDF for RAG” is not pdftotext and hope.

When should you use OCR on a PDF?

Use OCR when the page has no usable text layer — scanned or image-only — or when a layout pipeline must OCR detected regions; do not run full-page OCR as the default for every digital PDF.

Codex’s production-PDF blueprint (December 2025) makes OCR conditional: if a page yields no text elements, treat it as scanned. Unstructured’s fast strategy skips OCR by design; Firecrawl’s auto mode routes scanned pages into neural OCR and leaves text pages on the cheap path. Engine choice, character-error behaviour, and when to reject a page instead of indexing garbage live on OCR and scanned documents.

How should you handle tables inside PDFs?

Tables inside PDFs need structure-preserving extraction — an HTML or Markdown grid, or explicit cell objects — not a linear text stream; flattened tables are how RAG returns the wrong number from the right document.

Unstructured’s FAQ (May 2025) prefers HTML table serialization because merged cells and nested headers survive better than Markdown. Elasticsearch Labs documents an alternate table-focused parse path when tabular cells are the retrieval target; Nanonets and the KX LlamaParse walkthrough show the same fork: detect table regions and keep structure before any chunker runs. Extraction recipes and serialize-for-embedding detail belong on handling tables and structured data. If the symptom is already a wrong figure or orphan value, diagnose it on why RAG gets numbers and tables wrong.

How do you implement PDF parsing for RAG?

Implement PDF parsing as a typed stage — choose a family by document type, convert to elements or Markdown, attach source metadata, clean chrome, then chunk — not as a one-off script that dumps raw text into an embedder.

Named entry points as of July 2026 (verify import paths and versions before you pin them):

  • unstructured.partition.pdf.partition_pdf(…) with strategy=”auto” / “hi_res” / “fast” (BuildRag; Unstructured Part 2).
  • Docling’s DocumentConverter for self-hosted Markdown / JSON export (BuildRag; Firecrawl).
  • LlamaParse / LlamaCloud API when you already sit on LlamaIndex and need cloud table-aware parse (KX Systems, 2024 walkthrough — confirm current package name; Firecrawl notes migration toward llama-cloud).
  • PyMuPDF (or PyMuPDF4LLM) as a fast text-only baseline for clean digital PDFs (superml; Fast.io).

Carry source, page, and element type in metadata from the first hop (superml’s metadata principle) so retrieval can filter later. Runnable, pinned pipelines belong on building the pipeline; the ingestion stage map is document ingestion.

What is PDF parsing for RAG?

PDF parsing for RAG converts a print-oriented PDF into structured text — typed elements, Markdown, or JSON — that a chunker can split without destroying reading order, tables, or section boundaries. The chunker never sees the original page; it only sees what the parser emitted, so a bad parse poisons every downstream embedding.

Why does pdftotext break multi-column PDFs?

PDFs store positioned glyphs, not a document tree. Simple text extractors often read down one column or interleave columns, producing jumbled sentences. Layout-aware parsers detect regions and reconstruct reading order before you chunk. Nanonets’ qualitative PyPDF dumps on multi-column S-1 pages show the failure mode; fix it with a layout model, not a smarter chunker.

Should I use Docling or Unstructured?

Match the tool to constraints, then measure on your documents. Docling is a strong self-hosted, open-source default when you want Markdown/JSON with layout and table structure and can run local models. Unstructured fits when you want semantic element types and Fast/Hi-Res/VLM/Auto strategy routing, including cloud deployment. Neither replaces measuring reading order and table grids on your own corpus.

Do I always need OCR for PDFs in RAG?

No. Use OCR when a page has no usable text layer (scanned or image-only) or when a layout pipeline must OCR detected boxes. Digital text-layer PDFs should stay on a fast text or layout path. Conditional OCR — detect empty text pages, then escalate — is the production pattern; engine depth lives on /ingestion/ocr.

Where do PDF tables belong in the pipeline?

Preserve table structure at parse time (HTML/Markdown grid or cell objects), then follow /ingestion/tables for extraction recipes. If the symptom is already a wrong number or orphan value, diagnose on /failures/tables. This page only owns the fork: do not flatten tables into linear text before chunking.

How do I choose a PDF parser without a public leaderboard?

Pick by document type (text-heavy digital, multi-column, table-heavy, scanned, mixed), run the same sample set through two candidates, inspect reading order and tables by eye, then measure retrieval on the chunks each produces. Feature comparison tables are not benchmarks — and this site will not invent a shared-corpus scoreboard.