When a recruiter writes "5 years of experience with SQL" into a job description, they have something specific in mind. What they mean, roughly, is: "this person has used SQL seriously enough that they can work independently on complex queries without coaching." What an ATS keyword filter sees is: does the word "SQL" appear in this resume?
The gap between intent and implementation is where good candidates disappear and mediocre ones pass through. Understanding the patterns that cause this mismatch is the first step to writing requirements that actually screen for what you care about.
The experience-year problem
Year counts are among the most misused screening criteria. "3 years of Python" doesn't distinguish between someone who spent 3 years writing automation scripts and someone who spent 3 years building distributed systems in Python. It also penalizes people who learned something intensively in less time.
More practically: ATS systems don't read years. They match keywords. A candidate who wrote "extensive Python development" is invisible to a "3 years Python" filter even if they're more qualified than someone who wrote "3 years Python experience" in their summary.
Candidates who know about year-count requirements adapt their language to satisfy filters, which erodes whatever signal those filters provided. A candidate with 2 intensive years of Python who knows the filter looks for 3 years will often add "Python development" references to earlier roles to stretch the apparent timeline. The filter is now measuring keyword distribution on the resume rather than the thing it was supposed to measure.
Compound requirements split across keywords
"Experience with data pipelines and orchestration tools (Airflow, Prefect)" reads cleanly to a human. An ATS keyword filter scanning for "Airflow" will surface any candidate who used Airflow for any purpose. A candidate who built Prefect-based pipelines without ever using Airflow may be more qualified but won't appear.
The underlying concept the recruiter cares about (pipeline orchestration competency) doesn't have a single canonical keyword, so the filter can only proxy it imperfectly.
This is particularly acute in technology hiring, where tool ecosystems evolve faster than job description writing practices. By the time "Kubernetes" became a standard keyword in infrastructure job descriptions, significant portions of the qualified candidate pool had been using orchestration tools under other names and frameworks. Keyword-based filtering in fast-moving technical domains is perpetually catching up to the terminology used by the best candidates.
Soft requirement phrasing that yields zero filter signal
"Strong communication skills" and "attention to detail" appear in most job descriptions and most resumes. They're too ubiquitous to filter on and too vague to evaluate even if you could. When these are the requirements a recruiter cares most about (often legitimately, for roles where they matter), keyword filters provide no help at all.
The irony is that many soft requirements matter enormously for role success and are genuinely predictable from certain kinds of resume evidence. "Produced written documentation intended for a non-technical audience" is evaluable from a resume's project descriptions and can proxy communication skill in a meaningful way. "Attention to detail" as a keyword does nothing. "Has produced technical specifications with documented version history and clear change rationale" does something. The shift is from trait language to output language.
Requirements written for the filter rather than the job
A fourth pattern that compounds all the others: job descriptions are increasingly written to produce filterable resumes rather than to describe what the job actually requires. When hiring managers know the JD will be run through an ATS filter, they add keywords for the filter, not for the candidate's information. This produces JDs that are legible to filter systems but opaque about what the role actually involves, which in turn produces candidates who were selected for keyword density rather than fit.
Breaking this cycle requires separating the job description (for candidates) from the screening rubric (for evaluation). The JD should describe the role honestly. The rubric should describe what a good candidate looks like. These are related but different documents, and conflating them -- writing the JD as a list of filter-friendly requirements -- produces worse outcomes at both ends.
What works instead
The solution isn't better keywords. It's abandoning the keyword model for the kinds of requirements where it doesn't work and replacing it with scored rubric criteria. Instead of "5 years Python," the criterion becomes: "has built production Python services that handle real operational load." That's evaluable from a resume's project descriptions and employment context, not from a keyword hit. It's also more directly related to what you actually want.
The criterion "has built production Python services handling real operational load" returns a useful signal from a resume regardless of how the candidate chose to describe their experience. A candidate who said "deployed high-traffic Python services" satisfies it. So does one who said "engineered Python backend serving 50K daily active users." The keyword approach would miss the second candidate if "Python" appeared in a different context. The output-based criterion finds both.


