Docling vs Marker: Which Document Parser Works Better for RAG Pipelines
I built a RAG pipeline for ingesting technical PDFs into a vector database. Docling was my first choice because it had RAG-native features. But after testing a batch of 500 documents, I started questioning that choice. A Reddit thread confirmed my suspicion: no single tool handles everything well.
The Short Answer
Docling excels at structured document extraction with metadata preservation and semantic chunking. Marker processes faster with good accuracy for simpler documents. For complex RAG pipelines requiring table extraction and document hierarchy, Docling wins. For speed-focused batch ingestion, Marker is better.
[Complex documents with tables/equations?] |-- YES --> Docling (semantic chunking, metadata) |-- NO --> Continue
[Speed critical for large batches?] |-- YES --> Marker (GPU-accelerated, fast) |-- NO --> Continue
[Scanned documents only?] |-- YES --> Consider olmOCR |-- NO --> Hybrid approachWhy I Started With Docling
Docling came from IBM in 2024. It was built specifically for enterprise RAG pipelines. The features that attracted me:
- Semantic chunking: Native support for splitting documents into RAG-ready chunks
- Metadata preservation: Headings, sections, page numbers, bounding boxes
- Multi-format support: PDFs, DOCX, PPTX, HTML, images
My first test looked promising:
from docling.document_converter import DocumentConverterfrom docling.datamodel.pipeline_options import PdfPipelineOptions, TableStructureOptions
pipeline_options = PdfPipelineOptions()pipeline_options.do_ocr = Truepipeline_options.do_table_structure = Truepipeline_options.table_structure_options = TableStructureOptions( do_cell_matching=True, mode=TableFormerMode.ACCURATE)
converter = DocumentConverter()result = converter.convert("research_paper.pdf")
# Rich structure for RAGfor table in result.document.tables: df = table.export_to_dataframe(doc=result.document) print(f"Table at page {table.prov[0].page_no}")The table extraction worked. Metadata was preserved. But then I ran it on 500 documents.
The Problem With Docling
My batch of 500 PDFs took 6 hours. Average processing time: 4-5 seconds per page for documents with tables. Memory usage spiked to 2GB when processing multi-column layouts.
I posted about my experience on Reddit. The response was blunt:
“Docling was part of the stack I use on VectorFlow, but I’ve recently been disappointed with it.”
“My tests so far show that marker is better than docling in most cases.”
That pushed me to test Marker.
Testing Marker
Marker’s pitch: speed-first conversion with deep learning models. GPU-accelerated batch processing. Optional LLM integration for enhanced extraction.
from marker.converters.pdf import PdfConverterfrom marker.models import create_model_dictfrom marker.config.parser import ConfigParser
models = create_model_dict()config_parser = ConfigParser({"output_format": "chunks"})
converter = PdfConverter( config=config_parser.generate_config_dict(), artifact_dict=models, renderer=config_parser.get_renderer())
rendered = converter("document.pdf")
for block in rendered.blocks: print(f"Type: {block.block_type}, Page: {block.page}")Marker processed my 500 PDFs in 2 hours. 1-2 seconds per page for simple documents. 3-4 seconds for complex ones. Memory stayed under 800MB.
But I noticed the gaps.
Where Marker Falls Short
Marker outputs chunks, but the metadata is thin. No section hierarchy tracking. Bounding boxes are page-level, not element-level. Table extraction works, but DataFrame export isn’t built-in.
For simple PDFs, Marker was fine. For research papers with equations, cross-references, and nested sections, the output lacked context. RAG queries returned chunks without knowing where they came from in the document.
Docling: "Section 2.3 / Methods / Table 1 at page 5, bbox (0.1, 0.2, 0.8, 0.4)"Marker: "Block type: Table, Page: 5"The difference matters when you need grounded RAG responses.
Table Extraction: The Real Test
I tested both on a complex financial report with merged cells and nested headers.
| Metric | Docling | Marker ||---------------------|--------------|--------------|| Merged cells | Preserved | Split || Nested headers | Detected | Missed || DataFrame export | Built-in | Post-process || Cell bounding boxes | Optional | Built-in || Processing time | 6 sec/page | 4 sec/page |Docling’s TableFormer model (ACCURATE mode) handled merged cells correctly. Marker’s deep learning model split merged cells into separate entries. Both extracted the data, but Docling’s structure was more usable.
OCR Comparison
I ran both on scanned documents (no embedded text).
# Docling: Flexible OCR backend choicefrom docling.datamodel.pipeline_options import EasyOcrOptions, TesseractOcrOptions
pipeline_options.ocr_options = EasyOcrOptions( lang=["en", "de"], use_gpu=True)# Can switch to Tesseract or RapidOCR
# Marker: Built-in OCR with character-level outputfrom marker.converters.ocr import OCRConverter
converter = OCRConverter(artifact_dict=models)rendered = converter("scanned_doc.pdf")# Output includes character positions| Feature | Docling | Marker ||---------------------|----------------------|---------------------|| OCR engines | EasyOCR/Tesseract/RapidOCR | Built-in || Language support | Configurable | Limited || GPU acceleration | Optional | Default || Output precision | Word-level | Character-level |Docling’s flexibility won here. I could switch OCR engines based on language needs. Marker’s built-in OCR was faster but less configurable.
Equation Parsing
For scientific documents, LaTeX extraction matters.
# Docling: Formula enrichmentpipeline_options.do_formula_enrichment = True # LaTeX output
# Marker: Block-level detectionequations = document.contained_blocks((BlockTypes.Equation,))for eq in equations: block = document.get_block(eq.id) print(f"Equation at polygon: {block.polygon}")Docling extracted equations as LaTeX strings. Marker detected equation blocks but didn’t convert to LaTeX. For RAG indexing, LaTeX is more useful than position data.
RAG Integration: The Critical Difference
This is where Docling’s design shows.
from docling.chunking import DocChunkfrom llama_index.readers.docling import DoclingReader
# Docling: RAG-ready chunks with metadatafor source in sources: doc_chunk = DocChunk.model_validate(source.meta["dl_meta"]) print(f"File: {doc_chunk.meta.origin.filename}") print(f"Section: {' / '.join(doc_chunk.meta.headings)}") print(f"Page: {doc_chunk.meta.doc_items[0].prov[0].page_no}") print(f"Bounding box: {doc_chunk.meta.doc_items[0].prov[0].bbox}")
# Marker: Requires post-processing for metadatafor block in rendered.blocks: print(f"Block type: {block.block_type}") # Less semantic contextWhen I queried my vector database, Docling-sourced chunks returned answers with source attribution: “From Section 3.1 on page 7.” Marker-sourced chunks returned answers without context.
Performance Benchmarks (Real Data)
| Metric | Docling | Marker ||-------------------------|-------------|-------------|| Simple PDFs (text-only) | 2-3 sec/page| 1-2 sec/page|| Complex PDFs (tables) | 4-6 sec/page| 3-4 sec/page|| Scanned PDFs (OCR) | 5-8 sec/page| 3-5 sec/page|| Accuracy (standard) | 95%+ | 93%+ || Accuracy (complex) | 90%+ | 85%+ || Memory usage | 1-2GB | 500-800MB |Marker was faster. Docling was more accurate on complex documents.
The Reddit Insight: Hybrid Approach
The Reddit thread had a key insight:
“First, I think people should let go of the idea that any OSS tooling can handle the entire parsing process for a document. You want to have something to handle the skeleton. Another for OCR-specific needs. Another for tables, equations, and such…”
That’s the answer. Neither tool does everything well. I ended up with a hybrid pipeline:
def parse_document(pdf_path): # Step 1: Detect structure with Docling docling_converter = DocumentConverter() structure = docling_converter.convert(pdf_path)
# Step 2: Route based on content type if len(structure.document.tables) > 0: # Use Docling's TableFormer for complex tables tables = extract_tables_docling(structure)
if has_equations(structure): # Use Docling's formula enrichment equations = extract_equations_docling(structure)
if is_scanned_image(structure): # Use specialized OCR (olmOCR or Tesseract) text = extract_with_olmocr(pdf_path)
# Step 3: Combine for RAG return merge_for_vector_db(structure, tables, equations, text)Who Should Choose What
Choose Docling If:
- Your documents have complex structures (multi-column, tables, equations)
- You need metadata for grounded RAG responses
- You’re building an enterprise pipeline with LangChain or Haystack
- Accuracy matters more than throughput
Choose Marker If:
- You’re processing large batches of simple PDFs
- Speed is your primary concern
- You have GPU resources available
- Your documents are mostly text with simple layouts
Consider olmOCR If:
- Your documents are scanned images
- OCR quality is the primary bottleneck
- You need character-level precision
Use Hybrid Approach If:
- You have mixed document types
- No single tool meets all requirements
- You can afford the complexity of multiple tools
What I Use Now
For my RAG pipeline:
- Docling for structure detection and table extraction
- Marker for fast batch processing of simple documents
- Tesseract for OCR on scanned pages
I route documents to the right tool based on initial structure detection. The extra complexity pays off in better RAG responses.
Summary
| Factor | Docling | Marker ||---------------------|--------------|--------------|| RAG Optimization | Native | Post-process || Table Extraction | Excellent | Good || OCR Flexibility | High | Limited || Processing Speed | Moderate | Fast || Metadata Richness | High | Low || Equation Parsing | LaTeX output | Block detect || Enterprise Ready | IBM-backed | Community |Neither tool wins outright. Docling is better for complex documents needing metadata. Marker is better for fast batch processing. The Reddit thread was right: use specialized tools for different tasks, then combine the results.
Final Words + More Resources
My intention with this article was to help others share my knowledge and experience. If you want to contact me, you can contact by email: Email me
Here are also the most important links from this article along with some further resources that will help you in this scope:
- 👨💻 Docling GitHub Repository
- 👨💻 Docling Documentation
- 👨💻 Marker GitHub Repository
- 👨💻 olmOCR Project
- 👨💻 Reddit Discussion: Docling Agent + Chunkless RAG
Oh, and if you found these resources useful, don’t forget to support me by starring the repo on GitHub!
Comments