Real numbers.
Head to head.
Extraction is the stage where pipelines bottleneck — and where marketing gets loud. This page is Xberg measured head-to-head against the frameworks teams actually consider, on the documents production actually sees.
Figures from the latest benchmark run — reproducible from the open-source harness.
Benchmarking
the landscape.
We could tell you Xberg is the best way to turn messy documents into clean text. Instead, we'll show you the data and let you decide.
How we evaluated
We benchmarked Xberg against seven open-source extraction frameworks — Docling, Unstructured, Tika, MarkItDown, PyMuPDF4LLM, LiteParse and MinerU — on a corpus of 518 real-world documents across 52 file types: 8,949 extractions per run. The documents reflect messy production reality: scanned and rotated pages, malformed email, right-to-left text, academic PDFs, and spreadsheets with merged everything. We measured performance across seven dimensions:
Throughput
How many megabytes of mixed real-world documents become clean text per second — the number that sizes your worker fleet and your bill.
See the results ↓Latency
Wall-clock time to extract one document, end to end — the number a user or an agent actually waits on.
See the results ↓Cold start
Process start to first extracted document. Serverless functions and autoscaled workers pay this tax on every scale-up.
See the results ↓Quality against ground truth
TF1 scores text completeness and SF1 scores structural precision, both against hand-verified extractions. Extraction quality is the ceiling on everything downstream.
See the results ↓Reliability
Every attempted extraction lands in exactly one bucket — completed, errored, timed out, or empty — and nothing leaves the denominator.
See the results ↓Memory under load
Peak resident memory per document — the number that sizes your containers and how many workers fit on a node.
See the results ↓Install footprint
A fresh install including required system dependencies: deploy weight, image size, and whether it runs at the edge at all.
See the results ↓The landscape,
across the tools.
Every framework × every dimension for the full corpus. #1 marks each column's leader — Xberg rows always show their true rank. Switch formats above and the whole board re-ranks.
| Framework | Throughput | Cold start | TF1 · text | SF1 · layout | Success rate | Peak memory | Install size |
|---|---|---|---|---|---|---|---|
| #11.70 MB/s | #1203 ms | #40.982 | #40.620 | #1100.0% | #132 MB | #7— | |
| #20.82 MB/s | #3512 ms | #50.979 | #30.631 | #2100.0% | #232 MB | #8— | |
| 0.10 MB/s | 206 ms | 0.973 | 0.415 | 100.0% | 68 MB | #135 MB | |
| 0.01 MB/s | 3.2 s | 0.993 | 0.651 | 92.9% | 303 MB | 1.36 GB | |
| 0.09 MB/s | 19.6 s | #11.000 | #10.884 | 51.4% | 1.01 GB | 2.97 GB | |
| 0.00 MB/s | 62.8 s | 0.907 | 0.618 | 45.5% | 3.59 GB | 2.65 GB | |
| 0.27 MB/s | 4.0 s | 1.000 | 0.495 | 97.5% | 187 MB | 205 MB | |
| 0.14 MB/s | 2.2 s | 0.825 | 0.451 | 97.7% | 355 MB | 52 MB |
Across the corpus, Xberg leads 4 of 7 columns; Docling takes tf1 · text, Docling takes sf1 · layout, LiteParse takes install size.
Always p50 · #1 = column leader · cold start & install size are framework-level
Megabytes in,
clean text out.
Megabytes of documents converted to clean, structured text per second.
Ingestion is throughput-bound — this decides how many workers you run and what the bill says.
Single-file mode, OCR off, identical hardware. Showing p50 of per-document throughput.
Across the corpus, Xberg leads throughput at 1.70 MB/s.
Milliseconds per document,
not seconds.
Wall-clock time to extract one document, end to end.
Latency is what a user or an agent actually waits on — and the tail is what pages you at 2am.
Per-document duration at p50, log scale. Extraction-only timings ship in the raw release.
Across the corpus, Xberg leads per-document latency at 22 ms.
The first document
shouldn't cost seconds.
Time from process start to the first extracted document — model loads, JVM boots and import chains included.
Serverless functions, autoscaled workers and CLIs pay this startup tax on every scale-up.
First-document latency at p50, log scale. Framework-level — identical across formats.
Framework startup, Xberg leads cold start at 203 ms.
Fidelity, measured against
ground truth.
Two F1 scores against hand-verified ground truth: TF1 measures how complete the extracted text is, SF1 how precise the layout structure — headings, tables, hierarchy — comes out.
Extraction quality caps everything downstream: retrieval can't find what extraction dropped.
Per-document F1 at p50. Rows ordered by corpus coverage, not score — a fidelity number counts for more when it spans more documents.
A high F1 near the bottom of the list is measured on a narrow slice of the corpus — rows are ordered by coverage, so the top rows earn their scores across the whole gauntlet.
Every file counts.
No hand-picking.
The outcome of every attempted extraction: completed, errored, timed out, or empty.
Production doesn't skip weird files — the failures are exactly the ones that page you at 2am.
Every attempt kept in the denominator. OCR off.
Across the corpus, Xberg leads reliability at 100.0%.
Peak memory,
under real load.
Peak resident memory per document during extraction.
Peak memory sets container size — and container size sets how many workers fit on a node.
RSS sampled across each run; per-document peak at p50.
Across the corpus, Xberg leads peak memory at 32 MB.
Deploy weight,
not dead weight.
Disk size of a fresh install, including required system dependencies.
Image size drives cold deploys, autoscaling lag, and whether it runs at the edge at all.
Fresh install incl. system dependencies, log scale. Framework-level — identical across formats.
Data issue: Xberg's install size is missing from this run's disk-size measurements, so it is shown as unavailable. Among measured frameworks, LiteParse is leanest at 35 MB while Docling's install tops 2.9 GB.
One gauntlet,
no favorites.
518 documents across 52 file types — chosen to be awkward, not flattering. Academic PDFs, scanned and rotated pages, malformed email, right-to-left text, spreadsheets with merged everything.
Every framework runs the identical corpus on identical hardware, driven by the same open-source harness — no vendor-tuned configs.
Every chart reads at p50 by default and flips to the p95 / p99 tail with one toggle. Averages hide the tail, and the tail is where pipelines fall over.
Errors, timeouts and empty output are recorded against the run — a framework doesn't get to skip the documents it can't handle.
The harness, the corpus and the raw results are public. One command reproduces every number on this page.