Tools,

docling-serve OCR, tested on a scanned PDF

504

after 120 seconds, with the job still running

Get the fixes

The default engine works

1,846 of 1,955 true words found

36.1 seconds for 10 pages

Send a scan to the convert endpoint:

curl -s -F files=@scan.pdf -F to_formats=md http://localhost:5001/v1/convert/file \
  | jq -r .document.md_content > scan.md

With no engine named, docling-serve 1.38.2 picked RapidOCR. A typed cover page in front of the scan changed nothing. It kept all 13 cover words and the same scan words.

Sync calls stop at 120 seconds

A sync call waits 120 seconds, then answers HTTP 504:

Conversion is taking too long. The maximum wait time is configure as DOCLING_SERVE_MAX_SYNC_WAIT=120.

EasyOCR hit it on just 10 pages, and the default engine on 40. The server went on and finished that long job, but the 504 carries no task id. That text was lost.

Raise the limit when you start the server:

docker run -d --name docling -p 127.0.0.1:5001:5001 \
  -e DOCLING_SERVE_MAX_SYNC_WAIT=600 \
  quay.io/docling-project/docling-serve-cpu

Long scans: use the async endpoint

It returns a task id at once. Poll it, then get the result:

id=$(curl -s -F files=@long.pdf -F to_formats=md http://localhost:5001/v1/convert/file/async | jq -r .task_id)
while curl -s "http://localhost:5001/v1/status/poll/$id?wait=10" | jq -e '.task_status | test("pending|started")' > /dev/null; do :; done
curl -s http://localhost:5001/v1/result/$id | jq -r .document.md_content > long.md

On 40 pages it got 7,384 of 7,820 words in 136 seconds.

Tesseract needs ocr_lang=eng

With ocr_preset=tesseract and no language, the call failed in 2 seconds with HTTP 404, Task result not found. The log named the real cause:

TesseractOcrCli has no model for the OCR language 'spa'. No traineddata file 'spa' is installed. Supported: iso:en.

The image holds English data only. The API docs show tags like en, and that failed the same way. The three-letter code worked and found the most words:

curl -s -F files=@scan.pdf -F to_formats=md -F ocr_preset=tesseract -F ocr_lang=eng \
  http://localhost:5001/v1/convert/file | jq -r .document.md_content > scan.md

Six setups, one scan

10 scanned pages, 1,955 true words
Setup Words found Seconds
Default (RapidOCR) 1,846 36.1
Tesseract, ocr_lang=eng 1,875 36.1
Tesseract, no ocr_lang 0 (404) 2.0
EasyOCR 0 (504) 120.2
EasyOCR, wait raised 1,427 174.2
Our OCR Actor 1,874 155.0

docling-serve ran in Docker on a Mac, limited to 2 CPUs. The Actor's time includes its start in the cloud.

No server? Use the Actor

The image takes 7.2 GB on disk. Our OCR Actor runs in the cloud instead. It takes a PDF URL and returns Markdown:

curl -s -X POST "https://api.apify.com/v2/acts/brasspage~pdf-ocr-to-markdown/run-sync-get-dataset-items" \
  -H "Authorization: Bearer $APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"documentUrls": ["https://api.apify.com/v2/key-value-stores/sTnmNrGoSsi7tLQvs/records/docling-serve-scan-10-pages.pdf"]}' \
  | jq -r '.[].markdown' > actor.md

It found 1,874 words, one fewer than Tesseract in docling-serve. It costs $0.006 a page.

How I tested it
  • Scan: the 10-page PDF of OCR in n8n, the first 10 of 55 proofread Wikisource book scans, with no text layer. 1,955 true words.
  • Typed page: a 13-word cover sheet, put in front of the scan. Long scan: the same 10 pages 4 times.
  • Score: true words found in order, with the scorer of the tessdata test.
  • quay.io/docling-project/docling-serve-cpu:latest on arm64: docling-serve 1.38.2, Docling 2.142.1, Tesseract 4.1.1. A fresh container for each setup, with --cpus 2.
  • The code blocks above are the files that ran. After start.sh I set the 2-CPU limit with docker update. The Actor: one real run.
What I did not test
  • GPU images, other OCR languages, and the VLM pipeline.
  • Tables, figures, handwriting, and faster or slower CPUs.
  • A proxy in front of the server, and the RQ or Ray engines.
Sources

Two ways to skip the work

Run it yourself. Our Apify Actor turns scanned PDFs into Markdown, tables included.

Try the Actor

Or send us the scan. Tack, our AI, does the job for $29, up to 50 pages. First page free.

Get one page free

Questions people ask

Which OCR engine does docling-serve use by default?

The preset auto. In the docling-serve-cpu image, version 1.38.2, it picked RapidOCR. It found 1,846 of 1,955 words on my 10-page scan.

How do I fix the docling-serve 504, Conversion is taking too long?

Sync calls wait 120 seconds. Start the server with DOCLING_SERVE_MAX_SYNC_WAIT=600, or send the file to /v1/convert/file/async and poll the task.

Why does docling-serve answer 404 with ocr_preset tesseract?

The OCR failed. The image has English Tesseract data only, and the default languages need more. Send ocr_lang=eng. The tag en failed too.