<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: resumap.io</title>
    <description>The latest articles on DEV Community by resumap.io (@resumap).</description>
    <link>https://dev.to/resumap</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4051816%2Ffa7844c4-8ba4-46b1-ab02-e245cdaecc43.png</url>
      <title>DEV Community: resumap.io</title>
      <link>https://dev.to/resumap</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/resumap"/>
    <language>en</language>
    <item>
      <title>We ran the same resume through 4 real ATS parsers in 36 layouts. Same text, different parses.</title>
      <dc:creator>resumap.io</dc:creator>
      <pubDate>Tue, 28 Jul 2026 17:12:58 +0000</pubDate>
      <link>https://dev.to/resumap/we-ran-the-same-resume-through-4-real-ats-parsers-in-36-layouts-same-text-different-parses-3mfc</link>
      <guid>https://dev.to/resumap/we-ran-the-same-resume-through-4-real-ats-parsers-in-36-layouts-same-text-different-parses-3mfc</guid>
      <description>&lt;p&gt;Every resume template on the internet is labelled "ATS-friendly". Almost nobody publishes what happens when you actually feed one to an ATS.&lt;/p&gt;

&lt;p&gt;So we did the boring version of that experiment. One resume — same person, same three jobs, same fifteen bullet points, same skill list — exported through 36 different templates from the same PDF renderer, then imported into four production applicant tracking systems and diffed field by field.&lt;/p&gt;

&lt;p&gt;The content never changed. Only the layout did. That turns out to matter more than it should.&lt;/p&gt;

&lt;h2&gt;
  
  
  The setup
&lt;/h2&gt;

&lt;p&gt;The corpus is one synthetic candidate: a backend engineer, three positions, fifteen experience bullets, one degree, and a skill list containing ten job-critical skills. Every template renders exactly this content — the only variable is how the layout orders the text stream inside the PDF.&lt;/p&gt;

&lt;p&gt;The four parsers:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Parser&lt;/th&gt;
&lt;th&gt;What it is&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Zoho Recruit&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Full ATS, "Import from Document" parser&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Manatal&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;AI-first ATS&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Workable&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Mid-market ATS, "Add candidate → Add resume"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Textkernel&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Not an ATS — the OEM parsing engine documented behind SAP SuccessFactors and iCIMS&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Textkernel is the interesting one. It's not a product job seekers ever see, but it's the engine under other people's ATSs, which means one parser's behaviour is inherited by a lot of enterprise hiring stacks.&lt;/p&gt;

&lt;p&gt;Before blaming any parser, we extracted the text layer from every PDF locally and diffed it against the source data. Every defect described below is parser-side: the words were present, in the right order, in the file.&lt;/p&gt;

&lt;h2&gt;
  
  
  Result 1: nothing is uniformly "ATS-friendly"
&lt;/h2&gt;

&lt;p&gt;Here's the same corpus across three of the four parsers.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Check&lt;/th&gt;
&lt;th&gt;Zoho Recruit&lt;/th&gt;
&lt;th&gt;Workable&lt;/th&gt;
&lt;th&gt;Textkernel&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Email parsed&lt;/td&gt;
&lt;td&gt;36/36&lt;/td&gt;
&lt;td&gt;36/36&lt;/td&gt;
&lt;td&gt;36/36&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Phone parsed&lt;/td&gt;
&lt;td&gt;36/36&lt;/td&gt;
&lt;td&gt;36/36&lt;/td&gt;
&lt;td&gt;36/36&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Location parsed&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;36/36&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;31/36&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;All 3 jobs segmented&lt;/td&gt;
&lt;td&gt;34/36&lt;/td&gt;
&lt;td&gt;36/36&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;31/36&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Education clean&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;35/36&lt;/td&gt;
&lt;td&gt;36/36&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;All primary skills kept&lt;/td&gt;
&lt;td&gt;27/36&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;36/36&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Look at the last two columns. Textkernel retained all ten job-critical skills from &lt;strong&gt;every single template, 36 out of 36&lt;/strong&gt; — the best skill extraction in the study. And the same parser dropped a location on five templates and mis-segmented work history on five. Workable was the mirror image: flawless on contact fields and job segmentation, 539 of 540 experience bullets recovered, but it mangled one degree glyph (&lt;code&gt;M.Eng&lt;/code&gt; came out as &lt;code&gt;N.Eng&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;"ATS-friendly" is not one property. It's a per-parser, per-field property, and a layout that's perfect for one engine can lose a field on another.&lt;/p&gt;

&lt;h2&gt;
  
  
  Result 2: the same word disappears depending on layout
&lt;/h2&gt;

&lt;p&gt;The most repeated defect in the whole study, across 36 templates of identical content, was this one on Zoho Recruit:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;8x  primary skills missing: React
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Eight templates lost &lt;code&gt;React&lt;/code&gt; from the parsed skill list. Twenty-eight didn't. Same word, same skills section, same generator — different position in the text stream because the layout put it somewhere else on the page.&lt;/p&gt;

&lt;p&gt;Zoho's overall picture, scored on a 22-check composite:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;22/22  →  23 templates
21/22  →  10 templates
20/22  →   2 templates
18/22  →   1 template
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Two thirds of the layouts parsed perfectly. The remaining third each lost one to four checks — and the losses were not random noise, they clustered on skills extraction (13 templates had at least one anomaly, 8 of them the &lt;code&gt;React&lt;/code&gt; case).&lt;/p&gt;

&lt;h2&gt;
  
  
  Result 3: the hard thing was easy, the easy thing broke
&lt;/h2&gt;

&lt;p&gt;This one genuinely surprised me.&lt;/p&gt;

&lt;p&gt;Intuitively, pulling ten specific skills out of free text is the hard NLP problem, and figuring out "this block is job 1, that block is job 2" is bookkeeping. Textkernel inverted that: &lt;strong&gt;10/10 primary skills on all 36 templates&lt;/strong&gt;, with 54–69 distinct skills in structured output (median 68) — and then it merged or split work history on five of them.&lt;/p&gt;

&lt;p&gt;Segmentation is where layout hurts, because segmentation depends on reading order, and reading order is exactly what a two-column or sidebar layout scrambles. Skill extraction is bag-of-words-ish and survives almost anything.&lt;/p&gt;

&lt;h2&gt;
  
  
  Result 4: two columns are not automatically fatal
&lt;/h2&gt;

&lt;p&gt;The standard advice is "never use a two-column resume, the ATS can't read it". That's a decent heuristic aimed at a real failure mode, but it's the wrong diagnosis.&lt;/p&gt;

&lt;p&gt;The failure mode isn't columns. It's &lt;strong&gt;text-stream order&lt;/strong&gt;. A PDF has no concept of columns — it has a sequence of positioned text runs, and the parser reads that sequence. If the generator emits the sidebar interleaved with the main column, you get &lt;code&gt;Skills Senior Backend React Engineer&lt;/code&gt; and the parse falls apart. If the generator emits the main column fully, then the sidebar, a two-column layout parses exactly like a one-column one.&lt;/p&gt;

&lt;p&gt;Several of the two-column layouts in this corpus scored 22/22 on Zoho and 3/3 positions on Textkernel. Several one-column layouts didn't. The column count didn't predict the outcome; the emission order did.&lt;/p&gt;

&lt;p&gt;Practical version for anyone generating PDFs: &lt;strong&gt;check what your text layer actually says&lt;/strong&gt;, don't reason about what the page looks like.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# what the parser sees, not what you see&lt;/span&gt;
pdftotext &lt;span class="nt"&gt;-layout&lt;/span&gt; your-resume.pdf - | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-40&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If that output reads like a resume, parsers will mostly cope. If it reads like two documents shuffled together, no amount of "ATS-friendly" branding saves it.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I'd take away from this
&lt;/h2&gt;

&lt;p&gt;Three things, in descending order of confidence.&lt;/p&gt;

&lt;p&gt;Contact details are basically solved. Email and phone came back 36/36 on every parser we tested. Nobody is losing an interview because a parser couldn't find their email.&lt;/p&gt;

&lt;p&gt;Skills and work-history segmentation are where layout actually bites, and they fail on &lt;em&gt;different&lt;/em&gt; templates for &lt;em&gt;different&lt;/em&gt; parsers, so there's no single layout that's optimal everywhere. Pick one that's boring in emission order and you're covering most of the field.&lt;/p&gt;

&lt;p&gt;And the checkable claim beats the branded one. Any tool can print "ATS-friendly" on a template. It costs nothing and means nothing. What costs something is running the corpus and publishing what broke — including the five templates where our own output tripped a parser.&lt;/p&gt;

&lt;h2&gt;
  
  
  The data
&lt;/h2&gt;

&lt;p&gt;We published all of it — the per-template results, the raw parser responses, the CSV exports and the PDF corpus itself, so anyone can re-run this against their own ATS:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://resumap.io/articles/zoho-recruit-ats-parsing-test" rel="noopener noreferrer"&gt;Zoho Recruit round&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://resumap.io/articles/workable-parsing-test" rel="noopener noreferrer"&gt;Workable round&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://resumap.io/articles/textkernel-parsing-test" rel="noopener noreferrer"&gt;Textkernel round&lt;/a&gt; — the SuccessFactors / iCIMS engine&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://resumap.io/articles/manatal-ai-match-score-test" rel="noopener noreferrer"&gt;Manatal round&lt;/a&gt; — AI match scoring rather than parsing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Full disclosure: the 36 templates are the ones from &lt;a href="https://resumap.io" rel="noopener noreferrer"&gt;Resumap&lt;/a&gt;, which I work on. That's also why the failure cases are in here — we found five templates of our own that a parser stumbled on, and the honest thing is to publish those alongside the wins rather than round them off.&lt;/p&gt;

&lt;p&gt;If you've run a similar test against Greenhouse, Lever or Ashby, I'd genuinely like to see the numbers — those are the three we haven't been able to get trial access to.&lt;/p&gt;

</description>
      <category>career</category>
      <category>testing</category>
      <category>pdf</category>
      <category>resume</category>
    </item>
  </channel>
</rss>
