A practical method for developers, with real examples from software engineering job descriptions.
Most advice about "ATS keywords" boils down to "use the words in the job description." That's true, but it's not a method. It leads people to paste a block of buzzwords into their skills section and wonder why nothing changes.
This post is a repeatable process: you extract the right terms, sort them by priority, find where they honestly belong in your resume, and stop before it turns into a word cloud. It takes 15–20 minutes per application once you've done it a couple of times.
Why matching matters at all
When you apply through a company's careers page, your resume usually goes into an applicant tracking system. It extracts the text, builds a candidate profile, and lets recruiters search and filter. A recruiter looking for a backend engineer might search for "Go," "Kubernetes" or "distributed systems."
If you have those skills but your resume calls them something else, or buries them in a paragraph, you're harder to find. Keyword matching is about being findable for the things you can actually do. It's not about fooling software.
(Matching only works if your resume's text extracts cleanly in the first place. If you're not sure, this guide to what ATS parsers read and what breaks them covers headings, dates, columns and file types.)
Step 1: Read the JD once for meaning, then again for terms
On the first pass, just answer: what is this person actually going to do? Build APIs? Own infrastructure? Ship UI?
On the second pass, highlight terms in four buckets:
| Bucket | Example terms from a backend JD |
|---|---|
| Role title | Backend Engineer, Software Engineer II, SDE-2 |
| Hard skills / tools | Go, PostgreSQL, Kafka, Kubernetes, AWS, gRPC |
| Practices | code review, CI/CD, observability, on-call |
| Domain / context | payments, high-throughput, B2B SaaS |
Also note where each term appears. Words in the job title, the first paragraph, and the "Requirements" or "Must have" list matter most. "Nice to have" matters less.
Step 2: Sort into must-have vs nice-to-have
Make two short lists:
- Must-have (title + required skills + anything repeated): usually 5–10 terms.
- Nice-to-have (preferred tools, context words): another 5–10.
If a term appears in the title, the summary and the requirements, it's almost certainly a must-have.
Step 3: Audit your resume against the list
Go through each term and mark it:
- ✅ Present: already in your resume, in the employer's wording
- 🔁 Different wording: you wrote "Postgres," they wrote "PostgreSQL"; you wrote "K8s," they wrote "Kubernetes"
- ➕ Missing but true: you've done it, you just didn't mention it
- ❌ Missing and not true: you don't have this skill
Your edits come from 🔁 and ➕. The ❌ list is information, not a to-do list. Don't add those.
If you want a quick way to do the first pass, a tiny script works:
import re
jd = open("jd.txt").read().lower()
resume = open("resume.txt").read().lower() # paste your resume's extracted text here
terms = ["go", "postgresql", "kafka", "kubernetes", "aws", "grpc",
"ci/cd", "observability", "code review", "distributed systems"]
for t in terms:
in_jd = len(re.findall(r"\b" + re.escape(t) + r"\b", jd))
in_cv = len(re.findall(r"\b" + re.escape(t) + r"\b", resume))
status = "OK " if in_cv else "MISSING"
print(f"{status} {t:<20} JD:{in_jd} resume:{in_cv}")
It's crude (it won't know "Postgres" equals "PostgreSQL"), but it makes the gaps obvious. Get resume.txt by opening your PDF, selecting all, and pasting into a text file; that also confirms your PDF has real text.
Step 4: Put each keyword where the proof is
A keyword is strongest when it appears in two places: your Skills section (so it's searchable and scannable) and a bullet (so it's credible).
Skills section: reorder so the JD's must-haves come first. Don't delete the rest of your stack, just move it down.
Bullets: rewrite one or two bullets per relevant role so they show the skill in use.
Before:
Worked on backend services for the payments team.
After:
Built and maintained Go services for payment reconciliation on PostgreSQL; added tracing and dashboards that cut time-to-diagnose for on-call issues.
The second bullet hits "Go," "PostgreSQL," "payments" and "observability" (via tracing and dashboards) because that's what the work was. Only write what's true; if you don't have a result you can stand behind, describe the work clearly and skip the result.
Summary / title line: if the JD says "Backend Engineer" and your summary says "Full-stack developer," and backend really is your strength, adjust the summary to lead with backend.
Step 5: Use their wording, once
If the JD says "CI/CD" and you wrote "build pipelines," use "CI/CD" at least once. If they say "React.js" and you wrote "React," either is fine for humans; for search, matching their exact form once doesn't hurt.
You don't need to repeat a keyword five times. Once in Skills and once or twice in context is plenty.
Step 6: Stop before it becomes stuffing
Signs you've gone too far:
- Your Skills section has 40 items
- The same term appears in every bullet
- You've added tools you've only read about
- Reading it aloud sounds like a tag cloud
Recruiters read the shortlisted resumes, and interviewers ask about every line. Stuffing helps you get found and then hurts you in the room.
A worked mini-example
JD excerpt (frontend role):
We're looking for a Frontend Engineer with strong React and TypeScript skills to build our design system. Experience with accessibility (WCAG), testing (Jest, Playwright) and performance optimisation is required. Next.js is a plus.
Must-haves: Frontend Engineer, React, TypeScript, design system, accessibility/WCAG, Jest, Playwright, performance
Nice-to-have: Next.js
Resume audit:
- React ✅, TypeScript ✅
- "Component library" 🔁 → also say "design system" if that's what it was
- Accessibility ➕ (you fixed keyboard navigation but never mentioned it)
- Jest ✅, Playwright ❌ (you've used Cypress, not Playwright: list Cypress, don't claim Playwright)
- Performance ➕ (you reduced bundle size)
Edited bullet:
Built a shared React + TypeScript component library (internal design system) used across three product teams; added keyboard navigation and ARIA labels to meet WCAG guidelines, with Jest and Cypress tests.
Doing this faster
The manual method above is the most reliable because you're the one judging what's true. Tools can speed up the comparison step.
If you'd rather not run a script, several resume tools offer job-description matching. The one I'm building, Imperfectors, has job-description keyword matching on its Pro plan (₹499/month): paste a JD and see which keywords your resume matches and which are missing. The resume builder itself is free. Whatever tool you use, treat its output as a checklist, not a verdict, and apply the "only if it's true" rule.
FAQ
How many keywords should I match?
There's no magic number. Aim to cover the must-haves you genuinely have, in Skills and in at least one bullet each.
Should I tailor my resume for every job?
For roles you really want, yes. A 15-minute pass is usually enough. For similar roles, keep two or three base versions (e.g. backend, full-stack) and tweak.
Is a "match score" the same as what the employer sees?
No. Each tool calculates its own score. Employers' systems vary. Use scores as a rough guide to gaps.
What about soft skills like "communication"?
Show them in bullets (e.g. "wrote the onboarding docs," "led code reviews"), rather than listing them as keywords.
Top comments (0)