Which tool fits which job#
Docling
Structured output (headings, tables, reading order, page provenance) from PDFs, Office files, HTML, images and audio, with OCR built in. MIT. The best fit for RAG pipelines and anything that must stay permissively licensed.
Marker
High-quality PDF-to-Markdown with an optional LLM pass for tables, math and forms. Code Apache-2.0; current model weights free below USD 5M funding/revenue, commercial licence above.
MinerU
Popular PDF and image parser with strong Chinese support and VLM back-ends. Apache-2.0 with extra conditions (thresholds and attribution).
PyMuPDF4LLM
Very fast Markdown from born-digital PDFs, good tables. AGPL-3.0 or a commercial licence from Artifex. OCR through Tesseract.
MarkItDown
Quick plain-text-style Markdown from many formats (Office, HTML, EPUB, ZIP, YouTube…). MIT. No local OCR or table structure for PDFs.
Unstructured
Partitioning library that splits documents into typed elements for ingestion pipelines. Apache-2.0. Local OCR via Tesseract.
Speed on the same PDF#
Measured by docling.org on a 4-vCPU cloud machine with no GPU: Docling 2.148.0 on 2026-11-06, the other tools on 27 Oct 2026. Lower is better.
Show data table
| s/page | |
|---|---|
| MarkItDown | 0.35 s |
| Unstructured | 0.36 s |
| PyMuPDF4LLM | 0.69 s |
| Docling (OCR off) | 1.83 s |
| Docling (default) | 6.58 s |
| Unstructured (hi_res) | 10.01 s |
| Marker | 90.66 s |
All tools ran on the same 9-page born-digital paper (the Docling technical report) on a 4-vCPU machine without a GPU. Docling's two bars show the default pipeline and the same pipeline with OCR off — OCR of the paper's figures is what costs the time. Marker 1.10.2 took 90.7 s/page here — its models are built for GPUs, so expect very different numbers on one. Unstructured's default strategy reads the text layer (0.36 s/page); its hi_res mode with table detection, which we used for the table test, took 10.0 s/page.
Scanned pages#
Measured by docling.org on 27 Oct 2026 (Docling 2.143.1): unique words (≥4 letters) of the born-digital text found in each output.
Show data table
| Words recovered | |
|---|---|
| Unstructured | 99.7% |
| Marker | 97.2% |
| Docling | 94.2% |
| PyMuPDF4LLM | 93.8% |
| MarkItDown | 0.0% |
Four pages of the same paper rasterised at 150 DPI with slight blur and skew, so there is no text layer. The score is the share of unique words (four letters or more) of the original text that appear in each output. PyMuPDF4LLM and Unstructured OCR through Tesseract, which must be installed separately (without it, PyMuPDF4LLM returned no text at all). Unstructured's text-only output scored highest; Docling's Markdown deliberately leaves out page headers, footers and the arXiv margin stamp, which costs a few points on this word-count metric. Docling's own engines are compared in the OCR guide — in our 2.148.0 re-run with Tesseract as its engine, Docling reached 96.1% at 5.5 s/page. This chart is from our 27 October run with Docling 2.143.1, on the scan copy all five tools were tested with.
The same table, five outputs#
Table 1 of the paper has a two-level header and rows where each cell holds two values (4 and 16 threads). No horizontal rules separate the sub-rows — a classic trap. Here is exactly what each tool returned (trimmed to the table):
| CPU | Thread budget | native backend - TTS | native backend - Pages/s | native backend - Mem | pypdfium backend - TTS | pypdfium backend - Pages/s | pypdfium backend - Mem |
|---------------------------------------------|-----------------|------------------------|----------------------------|------------------------|--------------------------|------------------------------|--------------------------|
| Apple M3 Max | 4 16 | 177 s 167 s | 1.27 1.34 | 6.20 GB | 103 s 92 s | 2.18 2.45 | 2.56 GB |
| (16 cores) Intel(R) Xeon E5-2690 (16 cores) | 4 16 | 375 s 244 s | 0.60 0.92 | 6.16 GB | 239 s 143 s | 0.94 1.57 | 2.42 GB ||CPU|Thread<br>budet|n<br>|ative back<br>|end<br>|pypi<br>|dfium bac<br>|i kend<br>|
|---|---|---|---|---|---|---|---|
||g|TTS|Pages/s|Mem|TTS|Pages/s|Mem|
|Apple M3 Max<br>(16 cores)|4<br>16|177 s<br>167 s|1.27<br>1.34|6.20 GB|103 s<br>92 s|2.18<br>2.45|2.56 GB|
|Intel(R) Xeon<br>E5-2690<br>(16 cores)|4<br>16|375 s<br>244 s|0.60<br>0.92|6.16 GB|239 s<br>143 s|0.94<br>1.57|2.42 GB|Thread nativebackend pypdfiumbackend
CPU
budget
TTS Pages/s Mem TTS Pages/s Mem
AppleM3Max 4 177s 1.27 103s 2.18
6.20GB 2.56GB
(16cores) 16 167s 1.34 92s 2.45| CPU | Thread | | native backend | | pypdfium backend | | |
|----------------------------------------|---------|----------------|----------------|---------|------------------|--------------|---------|
| | budget | TTS | Pages/s | Mem | TTS | Pages/s | Mem |
| Apple M3 Max<br>(16 cores) | 4<br>16 | 177 s<br>167 s | 1.27<br>1.34 | 6.20 GB | 103 s<br>92 s | 2.18<br>2.45 | 2.56 GB |
| Intel(R) Xeon<br>E5-2690<br>(16 cores) | 4<br>16 | 375 s<br>244 s | 0.60<br>0.92 | 6.16 GB | 239 s<br>143 s | 0.94<br>1.57 | 2.42 GB |<table><thead><tr><th rowspan="2">CPU</th><th rowspan="2">Thread budget</th><th colspan="3">native backend</th><th colspan="3">pypdfium backend</th></tr>
<tr><th>TTS</th><th>Pages/s</th><th>Mem</th><th>TTS</th><th>Pages/s</th><th>Mem</th></tr></thead>
<tbody><tr><td>Intel(R) Xeon</td><td>4</td><td>375s</td><td>0.60</td><td></td><td>239s</td><td>0.94</td><td></td></tr>
<tr><td>E5-2690</td><td>16 =.</td><td>244s</td><td>0.92,</td><td>FOGB</td><td>jy35</td><td>p57</td><td>742 GB</td></tr></tbody></table>| Tool | Header | All 24 numbers present | Row structure |
|---|---|---|---|
| Docling | Both levels kept, combined as “native backend - TTS” | Yes | 4- and 16-thread values merged into one cell; “(16 cores)” moved to the wrong row |
| PyMuPDF4LLM | Broken (“budet”, “ative back”) | Yes | Sub-rows kept with <br>; “(16 cores)” on the right row |
| MarkItDown | No table | Yes, as loose text | Lost; words run together (“AppleM3Max”) |
| Marker | Both levels kept as two header rows (group names in their own cells) | Yes | Sub-rows kept with <br>; “(16 cores)” on the right row — the most complete result: every row and number in place |
| Unstructured (hi_res) | Perfect: real rowspan/colspan two-level header | No — the Apple M3 Max row is missing | Remaining row partly garbled by OCR (“FOGB”, “jy35”) |
Licences: the row that decides most projects#
| Tool (version checked) | Code licence | Models / weights | Watch out for |
|---|---|---|---|
| Docling 2.148.0 | MIT | Layout model (Heron): Apache-2.0 · TableFormer: CDLA-Permissive-2.0 / Apache-2.0 (Hugging Face model cards) | Optional VLM presets have their own licences |
| Marker 2.0.0 | Apache-2.0 | Modified AI Pubs Open RAIL-M: free for research, personal use and startups under USD 5M funding/revenue | Commercial licence for the weights above that; version 1.10.2 (which we benchmarked) was GPL-3.0 |
| MinerU 4.0.12 | MinerU Open Source License (Apache-2.0 plus conditions) | — | Separate licence above 100M monthly users or USD 20M monthly revenue; must state that MinerU is used in online services |
| PyMuPDF / PyMuPDF4LLM 2.0 | AGPL-3.0 or Artifex commercial | — | AGPL obligations for network services and distributed software |
| MarkItDown 0.1.9 | MIT | — | Optional cloud services (Azure Document Intelligence, LLM captions) have their own terms |
| Unstructured 0.27.35 | Apache-2.0 | Uses third-party layout models for hi_res | Python 3.11–3.13 only (per its package metadata) |
Read from each package's PyPI metadata and licence file on 27 October 2026. This is not legal advice.
Features at a glance#
| Docling | Marker | MinerU | PyMuPDF4LLM | MarkItDown | Unstructured | |
|---|---|---|---|---|---|---|
| Inputs | 37 formats incl. PDF, Office, HTML, images, audio, XML | PDF, images; Office, HTML, EPUB with marker-pdf[full] | PDF, OFD, EPUB, HTML, images, CSV, RTF, OOXML, OpenDocument | PDF and other PyMuPDF formats | PDF, Office, HTML, EPUB, CSV, images, audio, ZIP, YouTube… | PDF, Office, HTML, email, EPUB, images and more |
| Local OCR for scans | Built in (RapidOCR default; 7 engines) | Built in (Surya) | Built in | Via Tesseract | No (cloud options only) | Via Tesseract (hi_res / ocr_only) |
| Table structure model | TableFormer | Yes | Yes | Rule-based from the text layer | No | Yes (hi_res) |
| Outputs | 12 incl. Markdown, JSON, HTML, DocTags, chunks | Markdown, JSON, HTML, chunks | Markdown, JSON | Markdown, JSON, text | Markdown | Element JSON |
| Built-in chunking for RAG | HybridChunker, HierarchicalChunker | — | — | Page chunks | — | By title / basic |
| Server / API | docling-serve, MCP server | Hosted API (Datalab) | Yes | — | MCP server | Hosted platform |
Format lists come from each package's own description or source tree in the versions above; “—” means we did not find it in the package, not that it is impossible.
What we could not test#
- Marker 2.0.0 runs its models through a local inference server (vLLM on NVIDIA GPUs, llama.cpp elsewhere). We could not get that server running in our sandbox, so we benchmarked Marker 1.10.2, the last release with the earlier architecture. Marker 2's speed and quality may differ substantially.
- MinerU 4.0.12 installed, but its bundled llama.cpp binary crashed on our machine (
free(): invalid pointer) before converting a page. We report its licence and formats only. - GPUs. Every number here is CPU-only. Model-heavy tools (Docling with OCR, Marker, MinerU) gain the most from a GPU; text-layer tools gain little.
How we tested#
- Each tool in its own Python 3.13 virtual environment, default settings, one warm-up conversion, then timed runs in the same process (medians of three runs; Marker, at up to several minutes per page, one timed run after a warm-up on the born-digital PDF and a single run with models already loaded on the scans).
- Hardware: 4 vCPU x86_64, 15 GB RAM, no GPU. Documents: the Docling technical report (arXiv 2408.09869, 9 pages) and a rasterised copy of its first four pages.
- We publish raw outputs on request: hello@docling.org. Tool maintainers who think a setting was unfair: tell us and we will re-run.
Frequently asked questions
Is Docling better than Marker?
It depends on the document and the licence you need. In our CPU test Docling's default pipeline ran at 6.6 s/page (1.8 s/page with OCR off) versus 90.7 s/page for Marker 1.10.2, and Docling is MIT-licensed throughout, while current Marker (2.0) model weights are free only below USD 5M funding or revenue. Marker can add an LLM pass (--use_llm) for harder tables and inline math.
Docling vs MinerU: which should I use?
Both are strong on PDFs and run locally. MinerU 4 supports many input formats and is especially popular for Chinese documents; its licence is Apache 2.0 plus extra conditions (a commercial licence above 100 million monthly users or USD 20 million monthly revenue, and attribution for online services). Docling is MIT, ships 37 input formats, and integrates with LangChain, LlamaIndex and Haystack. We could not benchmark MinerU 4 on our machine (see below).
Docling vs MarkItDown?
MarkItDown (MIT, Microsoft) is a lightweight converter: very fast, many formats, but its PDF path extracts plain text without OCR or table structure. In our test it ran at 0.35 s/page and recovered nothing from scanned pages. Use it for quick text dumps of born-digital files; use Docling when layout, tables or scans matter.
Docling vs PyMuPDF4LLM?
PyMuPDF4LLM is fast (0.69 s/page in our test) and kept every number of our test table, but PyMuPDF is licensed AGPL-3.0 or commercially by Artifex, which matters for closed-source and SaaS products. Its OCR needs Tesseract installed.
Is Docling free for commercial use?
Yes. Docling is released under the MIT licence, and its default layout and table models are published under permissive licences as well. Check the model card of any optional VLM preset you add, since those licences vary.
Sources
- Our benchmark method and hardware
- Marker README: licence and commercial usage (marker-pdf 2.0.0)
- MinerU Open Source License (mineru 4.0.12)
- PyMuPDF licensing (AGPL-3.0 or Artifex commercial)
- MarkItDown on GitHub (MIT)
- Unstructured open-source library (Apache-2.0)