What Is an ATS Score? How Resume Scores Are Calculated
An ATS score is a checker's estimate of how your resume fits a posting. How tools calculate it, Resume Matcher's formulas, and how to check yours by hand.
You paste a job description into a checker, upload your resume (CV), and a number comes back: 62 out of 100. That number is an ATS score. The tool behind it has estimated how an applicant tracking system might rate your file for that posting. The estimate has uses. It also invites misreading, because the systems employers run and the tools that score you are separate pieces of software, and because two checkers given the same resume return two different numbers. This post covers where the number comes from, how the common tools calculate it, what the formulas look like when the code is public, and how to check your own score with a text editor.
What is an ATS score?
An applicant tracking system (ATS) is the software a company uses to collect applications. It extracts the text from your file, splits it into fields such as name, employers, titles, dates and skills, stores the result, and gives recruiters a search box and filters over the whole pile. Greenhouse and Workday are two examples among dozens.
An ATS score is a number, on a 0 to 100 scale in most tools, that a piece of software assigns to your resume for one job description. Two kinds of software produce such numbers. The employer’s ATS can, in some products and some configurations, show recruiters a match indicator. Third-party checkers such as Jobscan, Resume Worded and SkillSyncer produce the number you see on your own screen. Someone searching for their ATS score means the second kind, and the two kinds share no scale.
ATS score vs resume score
The two terms overlap, and the difference is whether a job description went in. A tool that scores your file on its own, with no posting attached, measures writing and structure: quantified bullets, repeated phrases, section headings, dates it can parse. Vendors tend to call that a resume score. A tool that takes a posting measures overlap with that posting and tends to call the result an ATS score or match rate. Both are estimates produced outside any employer’s system, and the rest of this post applies to both.
What employer systems do with your resume
The documentation vendors publish describes parsing, storage and search far more than scoring.
Greenhouse’s support site describes keyword filtering during application review: a recruiter searches the full text of resumes and internal notes, the keyword in the search has to be an exact match for the wording in the application, and terms can be marked Preferred (any one has to appear) or Required (all of them have to appear). Automatic rejection exists, but Greenhouse’s application rules trigger on a candidate’s answers to application questions, such as work authorisation or location, and auto-reject is available on the Plus and Pro tiers. Neither article mentions a numeric resume score.
Workday does compute one, with limits it states itself. Its Candidate Skills Match uses machine learning to compare skills derived from the application with skills on the job requisition, gives more weight to the requisition’s required skills, and shows recruiters a band (Strong, Good, Fair, Low, Pending or Unable to Score) rather than a percentage. The admin guide says the score ignores how long ago or for how long a candidate used a skill, cannot be computed for unsupported resume formats or non-English documents, and that Workday plans to retire the feature in a future release.
Filtering and ranking of some kind is common. Harvard Business School’s Project on Managing the Future of Work surveyed employers in the US, UK and Germany for its 2021 report with Accenture, Hidden Workers: Untapped Talent. Joseph Fuller’s summary on HBS Working Knowledge reports that 63% of the employers surveyed used a recruitment management system (69% of those with more than 1,000 employees), and that among those users, 94% relied on the system for a first cut or ranking of middle-skill applicants and 92% for high-skill applicants.
So the ranking is real, it varies by vendor and by how each employer configured the product, and the number a recruiter might see has no published scale you can hold your resume against. For the mechanics of how those systems parse and rank, read how resume matching algorithms work, which covers the keyword, semantic and structured layers. This post stays with the number.
Where the number on your screen comes from
Third-party checkers each define their own score and their own target. As of October 2026, from each vendor’s site:
- Jobscan calls its number a match rate and says on its homepage that it rests on five priorities in order: hard skills, education level, job title, soft skills and other keywords, with resume word count and measurable results left out. Jobscan recommends 75%, adds that many of its users see success at 65%, and warns that pushing above 75% may require stuffing the resume with keywords.
- Resume Worded runs Score My Resume, 30 or more checks producing a 0 to 100 score, and calls 85 or above good and 90 or above ideal. Its separate Targeted Resume tool compares your resume to one posting and produces a Relevancy Score, where a result below 80 means important skills from the posting are missing.
- SkillSyncer scores your resume from 0 to 100 against a pasted posting, ranks keywords by how often the employer repeats them, and recommends 80 or above. You can exclude keywords that don’t apply to you and the score recalculates.
- Teal shows free users the top five keyword insights for an attached job and puts the full keyword list and a Match Score behind its paid Teal+ plan.
- Rezi builds a Rezi Score from 23 metrics and limits it on the free plan.
Same resume, three published targets (75, 80 and 85), one Match Score you pay to see, and one score cut down on the free plan. The threshold belongs to the tool that set it, and each tool chose its own keyword list, its own weights and its own extras. A 68 from one and an 81 from another can describe the same file on the same day.
How an ATS resume score is calculated
Most checkers combine three ingredients, and the differences between tools come down to weights.
Keyword overlap. The tool extracts terms from the job description, checks which ones appear in your resume, and divides. Variations: weighting a term by how often the posting repeats it, weighting hard skills above soft skills, treating the job title as its own check, and matching exact words or accepting synonyms. This ingredient carries most of the score in tools that take a job description.
Section checks. Is there a summary, an experience section, education, a skills list? Did the parser find an email address, a phone number, and dates it could read? Missing or unlabelled sections cost points.
Formatting checks. File type, whether the PDF carries a text layer, columns and tables that scramble reading order, fonts, page count. Tools that run without a job description lean on this group and on writing quality, such as quantified bullets and repeated phrases.
Then someone picks weights: perhaps 60% keywords, 20% sections, 20% formatting. The weights encode an opinion about what matters, and I have not found a vendor that publishes evidence that its weights predict interviews.
How to calculate an ATS resume score: a worked example with the code in the open
I maintain Resume Matcher, a free, open-source (Apache 2.0) AI harness for tailoring a resume to a job description, used by over 200,000 job seekers. It runs on your own machine with a model you bring, such as Claude, ChatGPT, Gemini, DeepSeek or a local model through Ollama. It is a tailoring tool and makes no claim to simulate any employer’s ATS. It does display two numbers, and because the code is public you can read the formulas rather than guess at them. That makes it a usable example of what a score is made of.
JD Match %
The Builder’s JD Match tab shows the job description beside your resume with matching words highlighted, plus a percentage. The computation, from apps/frontend/lib/utils/keyword-matcher.ts:
- Lower-case the raw job description and split it on anything that is not a letter, digit or hyphen.
- Keep tokens of three or more characters. Drop pure numbers. Drop a stop list of 172 words that covers English function words and job-posting filler such as “role”, “team”, “experience” and “skills”.
- Build the same set from your resume text.
- Count how many job-description tokens appear in the resume set. Membership is exact: “kubernetes” matches “kubernetes” and nothing else.
- Score = round(matched ÷ total job-description tokens × 100).
No AI runs in this calculation. Two limits worth knowing: the tokenizer handles ASCII, so words in Devanagari, Chinese or accented Latin are ignored; and the tab colours the percentage green from 50 and yellow from 30. Those colours are display choices in the interface. Nothing in the app treats them as pass marks, and you shouldn’t either.
ATS Score Breakdown
The tailor page shows a card labelled “ATS Score Breakdown” while a tailored preview is open. The score is out of 100 and comes from apps/backend/app/services/ats.py:
score = 0.55 × keyword_match + 0.25 × skills_coverage + 0.20 × section_completeness
- keyword_match: the model you connected extracts required skills, preferred skills and keywords from the posting. Code then matches each term whole-word and case-insensitive against your resume sections, excluding personal details, and divides matched by total.
- skills_coverage: the share of the posting’s required and preferred skills found in your resume.
- section_completeness: how many of summary, experience, education and skills are present, divided by four.
The recommendations under the card are fixed templates keyed to whichever component scored low. The card appears during preview and the number is not stored. The weights 0.55, 0.25 and 0.20 are a judgment call by the maintainers, and the repository’s own developer docs say not to claim commercial ATS accuracy for it. Read the card as a keyword-and-section heuristic, whatever the label says.
Both numbers exist to point at missing terms. The percentage summarises the list, and the list is what you act on.
How to check the ATS score of your resume by hand
You can reproduce the keyword-overlap part of any checker with a text editor and ten minutes, and the list of misses will teach you more than the number.
- Copy the posting’s requirements and responsibilities into a document.
- List the nouns. Languages, frameworks, tools, platforms, methods, domain terms, the job title, certifications. Skip verbs and filler. The resume keywords guide walks through this step with example terms for backend, frontend, data and DevOps roles.
- Mark repeats. A term the posting uses three times is one the hiring manager cares about.
- Tick each term that appears in your resume in the posting’s wording. “k8s” does not tick “Kubernetes”.
- Divide ticks by terms.
Example (fictional). A posting for a backend engineer at Larkspur Logistics yields twelve terms after step 2: Python, Django, PostgreSQL, Redis, Kafka, AWS, Terraform, Docker, Kubernetes, REST APIs, observability, on-call. Priya Nair’s resume carries Python, Django, PostgreSQL, AWS, Docker, Kubernetes, REST APIs and on-call: eight ticks. 8 ÷ 12 = 67%. The misses are Redis, Kafka, Terraform and observability. Priya ran Terraform for two years and wrote “infrastructure as code” instead, so one miss is a wording fix. She set up Grafana dashboards at her last job, which the posting calls observability, so that is a second wording fix. She has used Redis once and has no Kafka experience, so those stay off. Her honest ceiling for this posting is 10 of 12, or 83%, and the two remaining gaps are things to prepare for in an interview.
If you would rather script it, the JD Match formula fits in a few lines of Python:
import re
STOP = {"and", "the", "with", "for", "you", "our", "will", "role", "team",
"experience", "skills", "work", "strong", "ability", "years"} # extend as needed
def terms(text):
tokens = re.split(r"[^a-z0-9-]+", text.lower())
return {t for t in tokens if len(t) >= 3 and not t.isdigit() and t not in STOP}
jd = terms(open("posting.txt").read())
cv = terms(open("resume.txt").read())
matched = jd & cv
print(f"{round(len(matched) / len(jd) * 100)}% missing: {sorted(jd - cv)}")
Run it against a few postings and you will find yourself reading the second column and ignoring the first.
What a good ATS score is
There is no universal threshold, and anyone who gives you one without naming the tool is guessing. The vendors’ own targets differ by ten points. Employer systems, where they score at all, use bands or internal scales they don’t publish, and Workday says its scoring ignores how recent or how long your experience with a skill was. A 90 from a checker says your resume repeats the posting’s vocabulary. It says nothing about whether a recruiter at that company sorts by that vocabulary or opens files in the order they arrived.
Four questions give you more than the number:
- Does the resume contain, in the posting’s wording, each required skill you have? Each miss here is a free fix.
- Does your title line match the posting’s title, or include it in parentheses?
- Can you select and copy the text out of your PDF? If you can’t, no parser can read it either.
- Did you add anything you could not defend in an interview?
Jobscan’s warning about overstuffing above 75% is the right instinct. Once the terms you own are present, each added term you don’t own lowers your odds with the human reader who comes after the search. The score to aim for is the one where the missing list holds skills you lack and nothing else. The percentage that produces will differ by posting, and that is fine.
For a comparison of the checkers themselves, including what each free tier includes, read free ATS resume checkers compared. For turning the missing list into a tailored resume, start with how to tailor your resume to a job description.
If this post helped, star Resume Matcher on GitHub. Saurabh Rai builds it; follow him on GitHub, X and LinkedIn.
[This article was drafted, edited and formatted with the help of AI. Product facts were checked against the Resume Matcher source code, and outside sources are linked where they are used.]
Enjoyed this post? Star Resume Matcher on GitHub and follow along