Skip to content

Markdown to PDF Speed Comparison 2026 10 12

Milosz edited this page Oct 13, 2026 · 2 revisions

Markdown-to-PDF Speed Comparison 2026-10-12

RayoMD 4.0.0 against glu, Pandoc with Typst, md-to-pdf and Pandoc with XeLaTeX, converting the repository's tester.md, each tool as a fresh process, start to exit. The tools render different Markdown subsets, so this compares time to a finished PDF, not identical output.

Setup

  • AMD Ryzen 5 PRO 4650GE (12 threads), Linux, a Debian 12 Docker container with --network none, files on tmpfs. No CPU pinning: each tool used the cores it normally uses.
  • Median of 20 runs after one uncounted warm-up; output overwritten each run; every output checked to be a complete PDF.
  • scripts/compare_markdown_pdf_tools.py (tools/benchmark.py competitors), each command started in the document's folder.
Tool Version Command
RayoMD 4.0.0 (release rayomd-4.0.0-linux-x64) rayomd --export IN OUT native modern normal
glu 0.0.43 (release glu-linux-amd64) glu -q -o OUT IN
Pandoc + Typst Pandoc 3.12.1, Typst 0.15.1 pandoc IN -o OUT --pdf-engine=typst …
md-to-pdf 5.2.5, Node 22.23.3, Chromium 154 scripts/md_to_pdf_runner.cjs (A4, 20 mm margins)
Pandoc + XeLaTeX Pandoc 3.12.1, TeX Live 2022 pandoc IN -o OUT --pdf-engine=xelatex …

Both Pandoc routes read -f markdown+tex_math_single_backslash-raw_tex (so \[ … \] is display math, as in RayoMD, and a stray backslash in text is text) with DejaVu Sans and DejaVu Sans Mono; md-to-pdf ran Chromium with --no-sandbox (inside the container).

Documents

tester.md (5,162 bytes) tests fallbacks on purpose: two remote images, a missing local image, and a formula with an unknown TeX command. With those, glu stops with an error at the first image it cannot open, XeLaTeX stops at the unknown command, and Pandoc waits on the network for the remote images; RayoMD shows each as fallback text. So both measured documents leave them out:

Document Bytes SHA-256 (first 16) Contents
tester-local.md 4,880 4833c4ff1c15fe54 tester.md without lines 71-72, 106, 108 and 110; keeps the 1024×1024 RGBA mascot PNG
tester-noimg.md 4,750 0d35d7a801d21274 also without every other line starting with an image and the [logo-ref] definition

Results

Without images:

Tool Median Min Max vs RayoMD PDF bytes Formulas
RayoMD 1.58 ms 1.50 2.68 1× 81,649 typeset
glu 55.75 ms 53.74 57.48 35× 55,516 left as TeX source
Pandoc + Typst 112.24 ms 110.79 113.49 71× 97,626 typeset
md-to-pdf 1,669.84 ms 1,663.69 1,685.75 1,057× 113,072 left as TeX source
Pandoc + XeLaTeX 1,708.19 ms 1,695.76 1,716.33 1,081× 61,773 typeset

With the PNG:

Tool Median Min Max vs RayoMD PDF bytes
RayoMD 27.85 ms 27.52 28.56 1× 391,383
glu 86.47 ms 84.31 88.41 3.1× 347,399
Pandoc + Typst 148.45 ms 146.97 149.95 5.3× 370,198
md-to-pdf 1,744.79 ms 1,738.34 1,767.53 63× 403,496
Pandoc + XeLaTeX 2,651.78 ms 2,638.93 2,696.45 95× 305,037

Most of RayoMD's time with the PNG is decoding and re-encoding the 1024×1024 image. In one running process (rayomd --bench DOC OUT 5000 modern normal) each further export takes 0.21 ms without images and 0.25 ms with the PNG, which a running process caches.

Output

All five write a six-page PDF of the PNG document but glu (nine pages, its own layout). RayoMD and both Pandoc routes typeset the formulas; md-to-pdf and glu print them as TeX source, and glu's default font has no Cyrillic or Greek letters. Both Pandoc routes print the fenced math block as code.

Reproduce

In a container with the tools above (Pandoc's .deb, Typst's and glu's release archives, npm install md-to-pdf@5.2.5, Debian's texlive-xetex texlive-latex-recommended texlive-latex-extra texlive-fonts-recommended texlive-plain-generic lmodern fonts-dejavu-core chromium, PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium):

MD_TO_PDF_CHROME_ARGS=--no-sandbox python3 tools/benchmark.py competitors -- \
  --rayomd rayomd-4.0.0-linux-x64/rayomd --node-modules /opt/node/node_modules \
  --glu /opt/glu-linux-amd64/glu --document tester-noimg.md \
  --pandoc-from markdown+tex_math_single_backslash-raw_tex \
  --runs 20 --timeout 120 --preflight-timeout 120 --root benchmark-output/competitors-noimg

Run it again with --document tester-local.md for the PNG document.

RayoMD 4.1.0, 2026-10-13

RayoMD alone was measured again in the same container a day later, beside 4.0.0, the other tools not re-run: tester.md with its PNG in 9.7 ms with --no-image-cache (4.0.0 30.9 ms that day), 2.6 ms once the image is in its cache; without images 1.37 ms (4.0.0 1.34 ms). The comparison script now passes --no-image-cache to RayoMD builds that have it, so every run converts the image as the other tools do. Details: RayoMD 4.1.0 Images 2026-10-13.

Clone this wiki locally