Skip to content
ATSPrep
Build my resume

What actually breaks resume PDF extraction.

We generated 108 resume PDFs in 12 layouts and read each one back with the X-Ray's own code. The results, the data and the code are public.

Last updated 2026-07-31

The short version

Bad formatting rarely deletes your words. It moves them.

Pick a layout to see what PDF.js returned

PDF.js read backTwo columns, tight gutter

  1. Jordan Rivera EXPERIENCE (not a line the plain layout returned)
  2. Senior Backend Engineer Senior Backend Engineer, Northwind Systems (not a line the plain layout returned)
  3. jordan.rivera@example.com 2022 - Present (not a line the plain layout returned)
  4. 555-0142 - Migrated 47 services from virtual machines to Kubernetes across three (not a line the plain layout returned)
  5. Austin, TX (not a line the plain layout returned)
  6. regions. (not a line the plain layout returned)
Words back
97.9%
Order kept
83%
Lines welded
33.1%

The same split with the gutter reduced to eight points.

Outside a scanned image, at least 96.9% of words always came back. What broke was order: in the tight two-column layout, 33.1% of lines fused two unrelated lines into one. And 3 of the 12 conditions changed nothing, including fancy bullets and very tight line spacing.

Method

Each PDF was built with pdf-lib from one of 9 synthetic profiles, so the intended text is known exactly. PDF.js read it back with the X-Ray's own line rules.

The four measures, defined
  • Recovery: the share of intended words that came back at all.
  • Order: longest-common-subsequence overlap with the intended reading order.
  • Welding: the share of output lines fused from two unrelated source lines, counted only over words that appear once in the resume.
  • Blocks: whether each bullet stayed under its own role.

Welding exists because recovery misses the failure: a two-column resume recovers 97.9% of its words and still reads as nonsense.

Line rules: a new line when the vertical gap exceeds 2.5 units, a space when the horizontal gap exceeds max(1.1, 0.22 × glyph height).

Full results

Most damaged first. Means across the 9 profiles.

Extraction results for each formatting condition, most damaged first
ConditionRecoveryOrderWeldedBlocks
Scanned or exported as an image0%0%0%0%
Letter-spaced headings96.9%96.9%0%100%
Whole document letter-spaced96.9%96.9%0%100%
Table-style grid97.6%93.4%24.1%100%
Two columns, tight gutter97.9%83%33.1%100%
Two columns97.9%83.6%30.5%100%
Words positioned without spaces99.8%99.8%0%100%
Contact detail in the page margins100%93.7%0%100%
Single column, plain textControl100%100%0%100%
Very tight line spacing100%100%0%100%
Rotated sidebar100%100%0%100%
Decorative bullet glyphs100%100%0%100%

A scanned image has no text layer, so it is the only condition that loses the whole document.

The result we did not expect

Letter-spaced headings lose words. Drawing every line glyph by glyph lost no more (both 96.9%), so the extra spacing is the cause, not the splitting. Bigger spaced-out text is more fragile, which makes a spaced section heading the riskiest line on a resume.

The two conditions compared

per-character-tracking: Headings drawn one glyph at a time with extra tracking, which is how design tools apply letter spacing.

per-character-body: Every line, not only headings, drawn glyph by glyph. The space threshold scales with glyph height, which is why larger tracked text breaks first.

Get the data

Download the dataset (JSON)

All 108 rows, under CC BY 4.0. Reuse it, commercially too, and credit atsprep.com/research.

Versions, and how to rebuild it

Written by pdf-lib@1.17.1, read by pdfjs-dist@6.1.200, on node@24.13.0, 2026-07-31. Extraction changes between PDF.js releases, so the versions are part of the result.

The run is deterministic. The generator and runner live in scripts/research/; one command rebuilds every document and number:

node scripts/research/run-study.mjs

If you rerun it and get different numbers, we want to know.

What this does not show

  • The 108 resumes are synthetic: controlled, with no personal data, but tidier than real ones.
  • One reader, PDF.js. Employer systems use others and can behave differently.
  • It measures extraction, not hiring. A clean read predicts no interview (see the methodology).
  • Conditions were tested one at a time, never combined.

Written up in full

Run the same test on your own file.

The X-Ray reads your PDF with the same library and line rules, in your browser, and shows the text in the order it came back.

$0 forever · No watermark · No card · No account to start