<?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: Larbi Sahli</title>
    <description>The latest articles on DEV Community by Larbi Sahli (@larbisahli_).</description>
    <link>https://dev.to/larbisahli_</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%2F4024125%2F55077ca6-ddc5-4510-96cf-b9a0a44bf282.png</url>
      <title>DEV Community: Larbi Sahli</title>
      <link>https://dev.to/larbisahli_</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/larbisahli_"/>
    <language>en</language>
    <item>
      <title>LinkedIn profile optimization: Stop AI from hallucinating your tech stack</title>
      <dc:creator>Larbi Sahli</dc:creator>
      <pubDate>Sun, 09 Aug 2026 14:06:52 +0000</pubDate>
      <link>https://dev.to/larbisahli_/linkedin-profile-optimization-stop-ai-from-hallucinating-your-tech-stack-5a2o</link>
      <guid>https://dev.to/larbisahli_/linkedin-profile-optimization-stop-ai-from-hallucinating-your-tech-stack-5a2o</guid>
      <description>&lt;p&gt;An AI screening agent I was testing read a profile that listed Java, JavaScript, TypeScript, Python, and C++ in its skills section, and summarized the candidate as a "versatile full-stack polyglot." The person behind the profile was a backend Java engineer who had spent seven years on one payments platform. The model wasn't lying. It was averaging.&lt;/p&gt;

&lt;p&gt;I build AI career tools for a living, which means I spend a lot of time watching language models parse resumes, job postings, and profiles. The pattern is consistent: when your profile is ambiguous, the model doesn't leave a blank. It fills the gap with the statistically most likely answer. That's how a Django developer gets summarized as "experienced with Flask and FastAPI," and how "cloud experience" quietly becomes "AWS."&lt;/p&gt;

&lt;p&gt;More companies are putting an AI agent in front of the human recruiter, and that agent's summary is often the only version of you a hiring manager reads. LinkedIn profile optimization used to mean cramming keywords for a search index. Now it means writing so a language model can't misread you.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why the model invents skills you never claimed
&lt;/h2&gt;

&lt;p&gt;Large language models predict from co-occurrence. Skills that usually appear together in their training data get inferred together, whether or not you have them. List React with nothing else, and a summarizer will happily attribute "modern frontend ecosystem experience, likely Next.js and Redux." Say "built microservices" without naming a language, and you'll get whatever stack is most common next to that phrase, which is usually not yours.&lt;/p&gt;

&lt;p&gt;The hallucination happens exactly where you leave a gap. A vague headline, an unattributed bullet, a skill with no supporting evidence anywhere in your experience section. The model has to produce a confident summary either way, so it produces a confident guess.&lt;/p&gt;

&lt;p&gt;This cuts both ways. The same mechanism that invents skills also erases them. If your Rust work lives only in a skills tag and never appears in a single experience bullet, a summarizer will often drop it entirely, because unsupported claims get compressed out. The skills you never mention in context are the first ones to disappear.&lt;/p&gt;

&lt;h2&gt;
  
  
  Keyword stuffing worked on old ATS. It backfires on LLMs
&lt;/h2&gt;

&lt;p&gt;Classic applicant tracking systems (ATS) did exact-match filtering. If the posting said "Kubernetes" and your profile said "Kubernetes," you passed. That created a whole generation of advice: list everything, repeat everything, pad the skills section to 50 entries.&lt;/p&gt;

&lt;p&gt;An LLM-based screener reads the whole profile as one document and reasons about it. Feed it a wall of 50 skills and it can't rank your depth in any of them, so the summary comes out as "broad but unclear specialization." That's a polite way of saying generic, and generic loses to the candidate whose profile reads as "Go and Postgres, payments infrastructure, eight years."&lt;/p&gt;

&lt;p&gt;There's a second failure mode I see in testing: contradiction. When a skill sits in your list but appears nowhere in your work history, models increasingly flag it. A summary that includes "lists machine learning, though no ML work is evident in the experience section" is worse than not listing ML at all. The stuffed profile now reads as padded, and the model says so out loud.&lt;/p&gt;

&lt;h2&gt;
  
  
  Write claim-evidence pairs, not skill soup
&lt;/h2&gt;

&lt;p&gt;The fix is a rule I apply to every bullet: name the stack inside the sentence where the work happened. A model can only attribute a skill it can locate.&lt;/p&gt;

&lt;p&gt;Compare these two versions of the same work:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Weak: "Improved API performance and reduced infrastructure costs."&lt;/li&gt;
&lt;li&gt;Strong: "Cut p95 API latency from 800ms to 120ms by moving session storage from Postgres to Redis, then dropped compute spend by consolidating three ECS services into one."&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The first bullet gives a parser nothing to anchor. The second one lets it extract Postgres, Redis, ECS, a performance result, and a cost result, all attributed to you specifically. When the screening agent writes its summary, your actual stack shows up because it had somewhere to point.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9r7n6nc2zdxdoi1f8us8.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9r7n6nc2zdxdoi1f8us8.jpg" alt="A software engineer happily organizing her clean, focused tech stack on her profile at a sunlit wooden desk." width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then prune the skills section until it matches. My working test: would you take an interview question on it today? If not, cut it. Fifteen skills you can defend beat fifty you can't, and LinkedIn lets you pin your top skills, so put the three that define your target role first. Order is signal too.&lt;/p&gt;

&lt;p&gt;The same rules apply to your resume, since the AI reading it is often the same one reading your profile. I build Roleframe, so I'm biased, but the reason I know these failure modes so well is that &lt;a href="https://www.roleframe.ai/?utm_source=devto&amp;amp;utm_medium=social&amp;amp;utm_campaign=rYCH7oDJ" rel="noopener noreferrer"&gt;our tailoring pipeline&lt;/a&gt; parses job postings and resumes all day, and the resumes that map cleanly to a posting's requirements are always the ones where every skill claim sits next to its evidence.&lt;/p&gt;

&lt;h2&gt;
  
  
  Your headline and the first two lines of About do most of the work
&lt;/h2&gt;

&lt;p&gt;Parsers weight position. Your headline and the opening of your About section get read first and anchor everything that follows, the same way a recruiter's seven-second skim does.&lt;/p&gt;

&lt;p&gt;A headline like "Passionate technologist | Lifelong learner | Building the future" gives a model zero extractable facts, so it borrows facts from elsewhere and guesses the rest. Use the boring, dense formula instead: role, specialization, primary stack. "Senior Backend Engineer | Payments infrastructure | Go, Postgres, Kafka." Unglamorous, and unmistakable.&lt;/p&gt;

&lt;p&gt;Open your About section with the sentence you want quoted in the AI's summary, because it often will be, nearly verbatim: "Backend engineer with 8 years building payment systems in Go and Postgres, currently focused on ledger correctness at scale." After that anchor is set, you can write like a human for the rest of the section.&lt;/p&gt;

&lt;p&gt;One more cut: kill "familiar with" and "exposure to" lists. Models routinely drop the hedge and keep the skill, which turns "exposure to Kubernetes" into "Kubernetes experience" in the summary. If that inflation would hurt you in a technical screen, don't feed it to the parser. If the skill is real, state it plainly and back it with a bullet.&lt;/p&gt;

&lt;h2&gt;
  
  
  Test your profile the way a screener reads it
&lt;/h2&gt;

&lt;p&gt;You don't have to guess how a model reads you. Copy your full profile text, paste it into any chatbot, and run this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;You are a technical recruiter using AI to screen candidates.
Based only on the text below, summarize this candidate in five bullets:
their seniority, their specialization, their primary tech stack,
their strongest evidence of impact, and anything ambiguous or
unsupported. Do not infer skills that are not stated.

[paste profile]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then audit the output. Every skill in the summary that you don't actually have marks a spot where your profile is vague enough to invite a guess. Every real skill that's missing marks a claim with no evidence attached. Fix the source text, run it again, and repeat until the summary describes the engineer you'd defend in an interview. Even with the "do not infer" instruction, models drift, and where yours drifts is exactly where a screening agent will too.&lt;/p&gt;

&lt;p&gt;Thirty minutes of this loop does more than any keyword checklist, because you're testing against the actual reader.&lt;/p&gt;

&lt;h2&gt;
  
  
  The profile that survives is the specific one
&lt;/h2&gt;

&lt;p&gt;AI screening punishes exactly what old ATS advice rewarded. Vagueness used to be safe padding. Now it's an open invitation for a model to write your summary for you, with a stack you've never touched.&lt;/p&gt;

&lt;p&gt;So make yourself boring to a parser: a dense headline, an anchor sentence up top, stacks named inside the bullets where the work happened, and a skills list you could interview on tomorrow. Then run the paste-and-summarize test tonight. If the model gets you wrong, a screening agent already has.&lt;/p&gt;

</description>
      <category>career</category>
      <category>ai</category>
      <category>jobsearch</category>
      <category>programming</category>
    </item>
    <item>
      <title>Your spreadsheet job application tracker dies in week three</title>
      <dc:creator>Larbi Sahli</dc:creator>
      <pubDate>Wed, 05 Aug 2026 13:47:28 +0000</pubDate>
      <link>https://dev.to/larbisahli_/your-spreadsheet-job-application-tracker-dies-in-week-three-nfh</link>
      <guid>https://dev.to/larbisahli_/your-spreadsheet-job-application-tracker-dies-in-week-three-nfh</guid>
      <description>&lt;p&gt;Every developer job hunt I've watched up close starts with the same artifact: a clean Google Sheet. Company, role, link, date applied, status column with a dropdown. Maybe some conditional formatting if you're feeling fancy. By week three it's a graveyard of stale rows nobody has touched since the day they were created.&lt;/p&gt;

&lt;p&gt;I build career tooling for a living, so I've seen a lot of these sheets. Mine included. I ran one during my own last hunt and it failed me in exactly the ways I'm about to describe. The problem isn't discipline. The problem is that a spreadsheet is structurally the wrong tool for the job, and it fails in a way that costs you interviews without ever telling you it's failing.&lt;/p&gt;

&lt;h2&gt;
  
  
  A spreadsheet is a log. A job hunt needs a queue.
&lt;/h2&gt;

&lt;p&gt;Here's the core defect: a spreadsheet answers "what did I do?" A job hunt runs on "what do I do today?"&lt;/p&gt;

&lt;p&gt;Those are different data structures. A log is append-mostly. You add a row when you apply, you update a cell when something happens. Nothing in it ever demands your attention. A queue surfaces the next action and its deadline whether you feel like looking or not.&lt;/p&gt;

&lt;p&gt;So the follow-up email you meant to send five days after applying? It lives in your head, not in the sheet. The recruiter screen you should confirm? Same. The sheet records that you applied to 34 companies. It stays completely silent about the six of them where a two-line follow-up this week would actually move the needle.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fu6eqh86j3y5l3jmk4xd9.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fu6eqh86j3y5l3jmk4xd9.jpg" alt="An exhausted job seeker at a desk at dusk, overwhelmed by a complex application tracking spreadsheet on their laptop." width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Half of "I got ghosted" is you ghosting them
&lt;/h2&gt;

&lt;p&gt;Developers talk about ghosting like it's something companies do to candidates. Having sat on both sides, I'll say the uncomfortable part: a lot of it runs the other way.&lt;/p&gt;

&lt;p&gt;A recruiter replies Tuesday afternoon. You see it Thursday because it landed in a tab you don't check. You answer Friday evening. By Monday they've scheduled three other people, and your thread quietly dies. From your side it looks like ghosting. From their side, you were the slow one.&lt;/p&gt;

&lt;p&gt;When I've hired, the candidates who made it to interviews came overwhelmingly from the first few days after the posting went live. That's not a policy anyone writes down. It's just how pipelines work: once a hiring manager has four promising screens booked, application number 80 on day 19 gets a skim at best. Your spreadsheet doesn't capture any of this timing. "Applied: Oct 14" tells you nothing about whether you applied on day one of the posting or day twenty, and that single fact predicts more than almost anything else in the row.&lt;/p&gt;

&lt;h2&gt;
  
  
  What a job application tracker actually has to store
&lt;/h2&gt;

&lt;p&gt;Strip away the tooling debate and the requirements are short. If your tracker can't answer these four questions instantly, it's decorative:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;What's my next action for each live application, and when is it due?&lt;/li&gt;
&lt;li&gt;What did the posting actually say? (Postings get pulled. If you land an interview three weeks later, you'll want the exact text you applied against.)&lt;/li&gt;
&lt;li&gt;Which resume version did I send? The interviewer has it in front of them. You should too.&lt;/li&gt;
&lt;li&gt;How long did each application sit between "found it" and "applied"?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;As a data model, it looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Application&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;company&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;postingUrl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;postingText&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;   &lt;span class="c1"&gt;// save the full text; the URL will 404 eventually&lt;/span&gt;
  &lt;span class="nl"&gt;resumeSent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;    &lt;span class="c1"&gt;// the exact PDF you submitted, not "resume_final_v3"&lt;/span&gt;
  &lt;span class="nl"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;found&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;applied&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;screen&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;interview&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;offer&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;closed&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;statusHistory&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;at&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt; &lt;span class="p"&gt;}[];&lt;/span&gt; &lt;span class="c1"&gt;// timestamps, not one mutable cell&lt;/span&gt;
  &lt;span class="nl"&gt;nextAction&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;    &lt;span class="c1"&gt;// "follow up with recruiter", "send thank-you note"&lt;/span&gt;
  &lt;span class="nl"&gt;nextActionDate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// the field your spreadsheet doesn't have&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice what's absent from the typical sheet: &lt;code&gt;statusHistory&lt;/code&gt;, &lt;code&gt;nextActionDate&lt;/code&gt;, and &lt;code&gt;postingText&lt;/code&gt;. Those three fields are the whole game. A single mutable "status" cell destroys the timing data you'd need to see that, say, every application you sent within 48 hours of posting got a reply and nothing older did. That pattern is invisible in a flat sheet, and it's the most useful thing your own hunt can teach you.&lt;/p&gt;

&lt;p&gt;One side note on &lt;code&gt;resumeSent&lt;/code&gt;: store the actual PDF you submitted, and submit PDF by default. It renders identically everywhere, which is exactly what you want when a hiring manager opens it on a machine you don't control.&lt;/p&gt;

&lt;h2&gt;
  
  
  The number your sheet hides: time from found to applied
&lt;/h2&gt;

&lt;p&gt;Once you timestamp "found" separately from "applied", an ugly gap shows up for most people. The posting sat in a tab for four days. Why? Usually because applying properly meant tailoring the resume, and tailoring a resume by hand takes an evening you didn't have.&lt;/p&gt;

&lt;p&gt;So you face the classic trade: send the generic resume fast and get filtered by the applicant tracking system (ATS) and the recruiter skim, or tailor it properly and apply on day five, after the pipeline already has its shortlist. Both options lose, just at different stages.&lt;/p&gt;

&lt;p&gt;This is the exact problem I started Roleframe to fix, so I'm biased, but the premise is the same one this whole post argues: paste the posting, get a resume tailored to it in seconds instead of an evening, and &lt;a href="https://www.roleframe.ai" rel="noopener noreferrer"&gt;track the application in the same place&lt;/a&gt; so the follow-up date exists somewhere other than your memory. Tailored and early stops being a trade-off. Discount my opinion accordingly and check the reasoning yourself.&lt;/p&gt;

&lt;h2&gt;
  
  
  If you keep the spreadsheet anyway
&lt;/h2&gt;

&lt;p&gt;Fair enough. Spreadsheets are free and you already have one. Then make these changes tonight, because they fix the worst of it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add &lt;code&gt;next_action&lt;/code&gt; and &lt;code&gt;next_action_date&lt;/code&gt; columns. Sort the sheet by that date every morning. This single habit converts your log into a crude queue.&lt;/li&gt;
&lt;li&gt;Add a &lt;code&gt;found_date&lt;/code&gt; column next to &lt;code&gt;applied_date&lt;/code&gt;. Watch the gap between them. If it's regularly more than a day or two, that gap is where your interviews are leaking.&lt;/li&gt;
&lt;li&gt;Paste the full posting text into a notes cell the moment you find the job. Thirty seconds now saves you a dead link before the interview.&lt;/li&gt;
&lt;li&gt;Record the exact PDF filename you sent per application, and keep those files.&lt;/li&gt;
&lt;li&gt;Every Sunday, close out dead rows honestly. A sheet full of zombie "applied" statuses makes you feel busy and tells you nothing.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That setup holds together up to maybe 15 or 20 live applications. Past that, in my experience, the manual sorting ritual is the first thing to go, and once it goes you're back to a log.&lt;/p&gt;

&lt;p&gt;The deeper point stands regardless of tooling. A job hunt is a pipeline with time-sensitive state, and most rejections-by-silence aren't mysteries. They're missed follow-ups and late applications that no row in a sheet ever flagged.&lt;/p&gt;

&lt;p&gt;What does your setup look like, and what broke first? I've heard everything from Notion boards to a Kanban of email labels to one person running theirs in a Postgres instance. Genuinely curious what survives contact with week three.&lt;/p&gt;

</description>
      <category>career</category>
      <category>jobsearch</category>
      <category>productivity</category>
      <category>discuss</category>
    </item>
    <item>
      <title>Salary Negotiation Tips for Devs in a Buyer's Market</title>
      <dc:creator>Larbi Sahli</dc:creator>
      <pubDate>Mon, 03 Aug 2026 09:30:46 +0000</pubDate>
      <link>https://dev.to/larbisahli_/salary-negotiation-tips-for-devs-in-a-buyers-market-1a0m</link>
      <guid>https://dev.to/larbisahli_/salary-negotiation-tips-for-devs-in-a-buyers-market-1a0m</guid>
      <description>&lt;p&gt;Three years ago, countering a job offer was almost a reflex, and companies budgeted for it. Now the same counter feels risky. The recruiter has backup candidates, layoffs are fresh in everyone's memory, and you may have spent four months getting to this one offer. So a lot of developers sign the first number they see.&lt;/p&gt;

&lt;p&gt;That is usually an expensive mistake. The number you sign compounds through every raise, every bonus target, and every future offer that anchors on it. I run a career platform for engineers, which means I spend a lot of time talking to people mid-search and hearing how their offers played out. The pattern over the last few months is consistent: negotiation still works in a buyer's market. What changed is which asks work, and how you have to make them.&lt;/p&gt;

&lt;h2&gt;
  
  
  What changed, and what didn't
&lt;/h2&gt;

&lt;p&gt;What changed is your fallback position. In 2021, if one company wouldn't move, three others would call you next week. Today most candidates have one live offer at a time, comp bands are enforced instead of bent, and recruiters are less afraid of losing you because the pipeline behind you is full.&lt;/p&gt;

&lt;p&gt;What didn't change is the company's sunk cost. By the time you have a written offer, a hiring manager has read dozens of resumes, four to six engineers have spent hours interviewing you, and the recruiter has shepherded the whole thing for weeks. Restarting that process costs them a month or more, and the next candidate might fail the loop. You are not as replaceable at offer stage as you were at application stage. That asymmetry is your negotiating room.&lt;/p&gt;

&lt;p&gt;The other thing that didn't change: polite, specific counters almost never get offers pulled. In all the offer stories engineers have shared with me, the rescinded ones trace back to hostility, bluffing, or dragging the process out for weeks. Asking clearly for more is not on that list.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ask once, and put everything in the ask
&lt;/h2&gt;

&lt;p&gt;In 2021 you could go back and forth three times and nobody blinked. In this market, multiple rounds of counters read as "this person will be difficult after they join." One consolidated, well-reasoned counter reads as "this person knows what they want."&lt;/p&gt;

&lt;p&gt;So before you respond to the offer, decide on everything: base, sign-on bonus, equity, level, start date, remote days. Rank them. Then make one counter that includes your full ask, with the most important item first, and say explicitly what happens if they meet it. "If we can get there, I'll sign this week" is the single most persuasive sentence in a buyer's-market negotiation, because it converts your ask from an open-ended haggle into a closing condition.&lt;/p&gt;

&lt;p&gt;One more timing rule: never negotiate before the offer exists. If a recruiter asks for your salary expectations in the first screen, deflect. "I'd rather anchor on the role first. Can you share the band for this position?" In a growing number of US states the band is already in the posting, so asking for it is unremarkable. Giving a number before you've demonstrated your value only caps your ceiling.&lt;/p&gt;

&lt;h2&gt;
  
  
  The levers that still move
&lt;/h2&gt;

&lt;p&gt;Base salary is the stiffest lever right now. Bands exist, finance enforces them, and a recruiter who says "the band is capped" is usually telling the truth. Don't burn your one counter fighting a wall. Redirect the same dollar amount to levers with more give.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvn5xcqq2whlbib9epm8s.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvn5xcqq2whlbib9epm8s.jpg" alt="A developer calmly discussing terms over the phone in a warm, dimly lit room, representing salary negotiation." width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Sign-on bonus.&lt;/strong&gt; The most flexible lever I see. It's a one-time cost, it doesn't break the band, and it doesn't create a precedent the manager has to defend at review time. If base is capped, ask for the gap as a sign-on.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Level.&lt;/strong&gt; If your offer sits at the top of a band, ask whether you were evaluated for the next level. A level bump changes your entire comp trajectory, and hiring managers sometimes have more latitude on level than on dollars within a level.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Equity and refreshers.&lt;/strong&gt; Startups in particular often have more room in options than in cash. At larger companies, ask for a committed equity refresh review at 12 months instead of more shares today.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The cheap stuff.&lt;/strong&gt; Start date, extra PTO, a fixed number of remote days, conference budget. These cost the company little and are often granted just to close you. Put one or two in your counter so there's something easy to say yes to.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  A script that works when you're not holding the cards
&lt;/h2&gt;

&lt;p&gt;Deliver the counter by email after a warm verbal thank-you, so there's a written record and the recruiter can forward it internally without paraphrasing you. Here's the shape that works:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Thank you again for the offer. I'm excited about the team and the work
on [specific project], and I want to get to a yes.

Based on the scope of the role, I was targeting total compensation
closer to [your number]. I understand the base band is firm, so here
is what would get me to sign this week:

- A sign-on bonus of [amount]
- A committed equity refresh review at 12 months
- A start date of [date]

If we can land there, I'm ready to sign.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A few rules baked into that script. It opens with enthusiasm, because the recruiter needs to believe you'll actually accept before they'll fight for you internally. It gives a specific number instead of "is there any flexibility," because vague asks get vague answers. It concedes the base band, which builds credibility for the rest of the ask. And it ends with a closing condition, not an open question.&lt;/p&gt;

&lt;p&gt;One thing the script must never contain: a competing offer you don't have. Recruiters at companies in the same market talk, and timelines are easy to verify. If you get caught bluffing, the offer is gone and so is your reputation with that recruiter. Mention other processes only if they're real, and only as loosely as "I'm in late stages elsewhere."&lt;/p&gt;

&lt;h2&gt;
  
  
  Your bargaining power is built before the offer
&lt;/h2&gt;

&lt;p&gt;Every script above works better when it isn't a bluff. The engineers I've seen negotiate the largest improvements this year all had the same thing: a second offer, or at least a final-round loop, landing in the same two-week window. Nothing you say at offer stage substitutes for an actual alternative.&lt;/p&gt;

&lt;p&gt;Which means the real negotiation happens weeks earlier, in how you run your search. Parallel offers come from parallel pipelines, and parallel pipelines come from applying early to a lot of well-matched roles with a resume tailored to each one, because recruiters work the first strong applications hardest and many postings are effectively decided before week two. I build Roleframe, so I'm biased, but this is exactly the problem it exists to solve: &lt;a href="https://www.roleframe.ai" rel="noopener noreferrer"&gt;paste a posting, get your resume tailored to that job in seconds, and apply while the req is fresh&lt;/a&gt;, so you're running five processes instead of one when the offers start landing.&lt;/p&gt;

&lt;p&gt;If you can't get parallel offers, you can still manufacture time. When an offer arrives while another loop is mid-flight, tell the second company. "I have an offer with a deadline of Friday, and you're my first choice. Can we accelerate?" Companies compress week-long processes into days for candidates they want.&lt;/p&gt;

&lt;h2&gt;
  
  
  Before you sign
&lt;/h2&gt;

&lt;p&gt;Get the final terms in writing, including anything verbal like "we'll review your equity at 12 months." A promise that isn't in the offer letter or an email from the recruiter doesn't exist. Then sign, stop looking, and actually withdraw from your other processes. Reneging on a signed offer in a small industry has a long memory.&lt;/p&gt;

&lt;p&gt;The short version: negotiate once, negotiate specifically, aim your ask at sign-on and level instead of base, and build alternatives before you need them. The market decides how much room you have. Whether you use that room is still up to you.&lt;/p&gt;

&lt;p&gt;If you've negotiated an offer in the last year, I'd like to hear how it went, especially which levers moved and which didn't. Drop it in the comments.&lt;/p&gt;

</description>
      <category>career</category>
      <category>discuss</category>
      <category>jobsearch</category>
      <category>softwareengineering</category>
    </item>
    <item>
      <title>Laid Off? Your Cover Letter Gets Exactly One Sentence About It</title>
      <dc:creator>Larbi Sahli</dc:creator>
      <pubDate>Sun, 02 Aug 2026 15:29:20 +0000</pubDate>
      <link>https://dev.to/larbisahli_/laid-off-your-cover-letter-gets-exactly-one-sentence-about-it-57nj</link>
      <guid>https://dev.to/larbisahli_/laid-off-your-cover-letter-gets-exactly-one-sentence-about-it-57nj</guid>
      <description>&lt;p&gt;I run Roleframe, a resume-tailoring tool, which means I read a lot of cover letters written by people who just got cut. The pattern is depressingly consistent: smart engineers who can explain a distributed system in two sentences will spend an entire paragraph explaining, apologizing for, and relitigating a layoff that nobody asked them about.&lt;/p&gt;

&lt;p&gt;I wrote this because the fix is mechanical. There is a word budget for mentioning a layoff, there are phrasings that read as neutral and phrasings that read as red flags, and there is a specific sentence, the one right after the layoff mention, that decides how the rest of your letter gets read. All of it is learnable in ten minutes.&lt;/p&gt;

&lt;p&gt;So here is the whole system: when to mention a layoff at all, the exact wording swaps, how to pivot to what you bring to the role, and the traps that turn a neutral fact into a reason to pass on you.&lt;/p&gt;

&lt;h2&gt;
  
  
  The One-Sentence Rule
&lt;/h2&gt;

&lt;p&gt;A layoff gets one sentence in your cover letter, sometimes zero. Almost every mistake people make with this letter comes from breaking that rule: three sentences of context, an apology that was never owed, or a defensive aside about the former employer.&lt;/p&gt;

&lt;p&gt;Recruiters read layoff mentions constantly right now. A matter-of-fact line barely registers. What registers is everything around it, meaning how fast you get to the value you bring to this specific role.&lt;/p&gt;

&lt;h2&gt;
  
  
  Should You Mention the Layoff at All?
&lt;/h2&gt;

&lt;p&gt;Mention it briefly if the layoff explains a visible gap or an abrupt end date on your resume. Skip it entirely if there is no gap to explain yet. A cover letter is a sales document, and you do not spend prime real estate on things the reader was not going to ask about.&lt;/p&gt;

&lt;p&gt;The decision tree in practice:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Laid off in the last month or two, actively applying:&lt;/strong&gt; no mention needed. A recent end date on a resume is normal. Recruiters do not expect an explanation for a role that ended eight weeks ago.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gap of three months or more:&lt;/strong&gt; one factual sentence early in the letter, then move on. Unexplained gaps invite guessing, and recruiters guess worse things than a layoff.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Entire team or company shut down:&lt;/strong&gt; mention it, because it works in your favor. "Part of a company-wide reduction of 300 roles" makes clear the decision had nothing to do with your performance.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;You were fired, not laid off:&lt;/strong&gt; do not address it in the cover letter. A letter addressing being fired almost always does more harm than silence. Save the honest, rehearsed answer for the interview, where you control the tone and can show what you learned.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;One precision point. "Laid off" means the position was eliminated for business reasons. "Let go" is ambiguous and "terminated" reads as fired. Use "laid off" or "position eliminated in a restructuring" and nothing vaguer, because vague language makes recruiters fill in the blank themselves.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Word Budget: About 7%
&lt;/h2&gt;

&lt;p&gt;In a well-built layoff letter, the layoff mention runs about twenty words inside a 280-word letter. That sentence states the fact, signals it was a business decision, and can even sneak in a forward-looking point, wanting to join a company that is growing, for example. Then it disappears.&lt;/p&gt;

&lt;p&gt;That ratio, roughly 7% of the letter, is the ceiling. Everything after the layoff sentence should be forward-looking and mapped to the posting. Count your own draft's layoff words. If the layoff is 30% of your letter, you wrote a letter about your past instead of a letter about their opening.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wording Swaps That Change How You Read
&lt;/h2&gt;

&lt;p&gt;The framing that works is factual, brief, and points at the business rather than at you. The framing that fails is emotional, detailed, or apologetic. The gap between the two is often a single word choice.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Instead of writing this&lt;/th&gt;
&lt;th&gt;Write this&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Unfortunately, I was let go from my previous position.&lt;/td&gt;
&lt;td&gt;My role was eliminated when the company restructured its operations team.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;After a difficult period at my company, my position was terminated.&lt;/td&gt;
&lt;td&gt;I was part of a company-wide reduction affecting 200 roles across departments.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;I lost my job through no fault of my own.&lt;/td&gt;
&lt;td&gt;When [Company] closed its Austin office in June, my position was among those eliminated.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;I am currently unemployed and looking for a fresh start.&lt;/td&gt;
&lt;td&gt;Since the layoff, I have completed [certification] and am targeting roles where I can apply my experience in [specific area].&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Despite my strong performance, I was laid off.&lt;/td&gt;
&lt;td&gt;My team of six was eliminated in the restructuring; in my final year I had exceeded my targets by 22%.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Two patterns run through the good column. Scope makes it impersonal: "200 roles," "the Austin office," "my team of six" all say the cut was about the business. And an attached achievement or forward step keeps the sentence from being purely about loss. You never need to write "through no fault of my own," because the scope already proved it, and insisting on it out loud sounds defensive.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Sentence After the Layoff Is the Whole Game
&lt;/h2&gt;

&lt;p&gt;The sentence following your layoff mention is where the reader decides whether this letter is about your past or about their opening. Get to a specific, relevant result within one sentence of mentioning the layoff, and the layoff becomes a footnote.&lt;/p&gt;

&lt;p&gt;The pivot structures that work fastest:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The "which means" pivot:&lt;/strong&gt; "My role was eliminated in April, which means I can start immediately, and I would want to start with the [specific problem] your posting describes." Immediate availability is a genuine advantage. Use it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The achievement pivot:&lt;/strong&gt; state the layoff, then the single strongest number from the role you just left. The proximity does the arguing for you.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The requirements pivot:&lt;/strong&gt; go straight from the layoff sentence into a mapped list. "Your posting asks for X; here is exactly where I did X."&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The momentum pivot:&lt;/strong&gt; what you have done since. A certification finished, a project shipped, a skill built. Strongest when the gap is longer than three or four months.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Whichever you pick, run this test: mark where the layoff paragraph ends. If everything after that mark could have been written by a currently employed candidate, you did it right.&lt;/p&gt;

&lt;h2&gt;
  
  
  Never Diagnose the Old Company
&lt;/h2&gt;

&lt;p&gt;Any criticism of your former employer, even accurate criticism, costs you the interview more often than the layoff itself does. Hiring managers read "poor leadership decisions led to the layoffs" and hear a candidate who will describe them the same way in two years. It does not matter that you are right.&lt;/p&gt;

&lt;p&gt;The subtle versions slip through most often:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"Despite my contributions" or "despite consistently strong reviews." This frames the layoff as an injustice and you as someone still litigating it.&lt;/li&gt;
&lt;li&gt;"Mismanagement," "chaotic environment," "lack of direction." A diagnosis of the old company reads as blame, however diplomatically phrased.&lt;/li&gt;
&lt;li&gt;"I'm looking for a company that actually values its people." The word "actually" carries the whole grievance.&lt;/li&gt;
&lt;li&gt;Excessive detail about how the layoff was handled. Nobody reviewing your application needs to know about the severance terms or the Zoom call.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The clean alternative is gratitude plus facts. "I'm grateful for four years at Brightline and the team I got to build there" costs nothing and signals you will speak well of this employer too, someday. If you cannot write a warm sentence about the old company honestly, write nothing beyond the factual layoff line. Neutral silence is always available.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Generic AI Fails at Exactly This Letter
&lt;/h2&gt;

&lt;p&gt;Give a chatbot the prompt "write a cover letter, I was laid off" and you reliably get melodrama: "a challenging chapter," "resilience in the face of adversity," sometimes an outright apology for being unemployed. The model mirrors the emotional weight of the prompt, and a layoff is an emotionally weighted prompt. The output reads like a diary entry, the opposite of the twenty-word, matter-of-fact mention this letter needs.&lt;/p&gt;

&lt;p&gt;This is why we built cover letter generation at Roleframe as a multi-step pipeline instead of a single prompt. After the letter is drafted against the specific job posting, a recruiter-grade final review pass audits it the way a hiring manager would read it and strips defensive or overly emotional language. "Unfortunately" goes. "Despite my dedication" goes. Anything dwelling on the old employer instead of the new role's requirements gets cut or rewritten, so the layoff lands as one factual line and the rest stays pointed at what the posting asks for. You still review everything before it goes out, which is how it should be. But starting from a draft with the tone already right beats spending an hour talking a chatbot down from "navigating this difficult transition."&lt;/p&gt;

&lt;h2&gt;
  
  
  Speed Matters More After a Layoff
&lt;/h2&gt;

&lt;p&gt;Here is the blunt reason: you are applying alongside everyone else cut in the same wave, often from the same company, often to the same postings. The candidate whose application lands in the first day or two gets read while the recruiter is still forming their shortlist. Applying early is one of the few advantages fully within your control right now.&lt;/p&gt;

&lt;p&gt;The system that makes speed sustainable is a master resume you tailor per job instead of rewriting from scratch. Build one complete base resume for your target role, every achievement and number in it, then spin off a tailored version for each posting. In Roleframe that is a role workspace: paste the job, get a version tailored to it in seconds with the matching cover letter, and your master stays untouched for the next application. Twenty tailored applications in the time a from-scratch approach produces three.&lt;/p&gt;

&lt;p&gt;Two practical notes on the resume side. Your most recent role stays on the resume exactly as it would if you were still employed, just with an end date. No "(laid off)" annotation, no explanation in the bullets; the cover letter and the interview are where context lives. And when you export, send a PDF, which preserves your formatting no matter what opens it on the other end.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Whole Letter, Compressed
&lt;/h2&gt;

&lt;p&gt;The letter you need is shorter and calmer than the one you are tempted to write. One factual sentence about the layoff, scope included if it helps you. A fast pivot to a result the hiring manager cares about. Three paragraphs mapped to the posting. Nothing negative about anyone. Write it once, and the structure repeats for every application after it.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://www.roleframe.ai/cover-letter-examples/cover-letter-after-being-laid-off?utm_source=devto&amp;amp;utm_medium=social&amp;amp;utm_campaign=cover-letter-after-being-laid-off" rel="noopener noreferrer"&gt;roleframe.ai&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>career</category>
      <category>softwareengineering</category>
      <category>layoffs</category>
    </item>
    <item>
      <title>Why System Design Interview Prep Is Your Only Moat Against AI</title>
      <dc:creator>Larbi Sahli</dc:creator>
      <pubDate>Sun, 02 Aug 2026 13:36:53 +0000</pubDate>
      <link>https://dev.to/larbisahli_/why-system-design-interview-prep-is-your-only-moat-against-ai-5934</link>
      <guid>https://dev.to/larbisahli_/why-system-design-interview-prep-is-your-only-moat-against-ai-5934</guid>
      <description>&lt;p&gt;I build an AI product for a living, and I'll tell you what the models are good at: they write my CRUD endpoints, my Terraform, my test scaffolding, and they'd clear most LeetCode mediums faster than I can read the problem statement. What they have never once done is defend a decision when I push back on it. Ask a model "why Kafka and not Postgres here," then attack its answer twice, and it folds into a hedged survey of options. That gap, the ability to hold an engineering position under interrogation, is the last part of the technical interview AI can't do for you. It's also exactly what a system design round tests.&lt;/p&gt;

&lt;p&gt;So the hiring bar is moving. If your interview prep is still 80% algorithm grinding and 20% skimming a scalability blog the night before, you're preparing for the interview of five years ago.&lt;/p&gt;

&lt;h2&gt;
  
  
  The coding screen stopped measuring what it used to
&lt;/h2&gt;

&lt;p&gt;A take-home or an unproctored coding screen used to answer a real question: can this person write working code under mild pressure? Now it mostly answers a different one: does this person have a Copilot subscription? Every engineer I know uses AI for boilerplate, and every hiring manager I've talked to knows it. Some companies respond by proctoring harder. The smarter ones respond by shifting weight to the rounds where assistance doesn't help, and the design round is the biggest one.&lt;/p&gt;

&lt;p&gt;That shift is rational. If AI writes the syntax, the scarce skill is deciding what to build and what to trade away, then living with the consequences. A design interview is a 45-minute simulation of that job. The interviewer isn't grading whether you know that caches exist. They're grading whether you can commit to an architecture, explain what it costs, and adjust when they change a constraint.&lt;/p&gt;

&lt;p&gt;Which means the value of system design interview prep went up at the exact moment the value of LeetCode prep went down. But only one kind of design prep.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why LLMs recite patterns and still lose the room
&lt;/h2&gt;

&lt;p&gt;Here's the uncomfortable part. The way most people prep for system design, memorizing the standard playbook, produces answers indistinguishable from an LLM's. "Add a load balancer, cache the reads, shard the database, put a queue in front of the writes." A model will say that in two seconds, fully formatted, with a Mermaid diagram.&lt;/p&gt;

&lt;p&gt;Pattern recall is now free. It signals nothing.&lt;/p&gt;

&lt;p&gt;What models can't do, and what interviewers increasingly probe for, comes down to three things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Commitment.&lt;/strong&gt; An LLM gives you the trade-off table and leaves the choice to you. In an interview, you have to pick a side and own it. "I'd start with Postgres and I accept that we'll revisit this around 10k writes per second" is a position. "It depends on your requirements" is a shrug.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Context sensitivity.&lt;/strong&gt; The standard pattern is often wrong for the specific constraints on the whiteboard. A three-person startup that "shards for scale" on day one has failed the interview even though every individual sentence was textbook-correct.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Surviving the follow-up.&lt;/strong&gt; Interviews are adversarial by design. "What breaks first?" "What if the queue backs up for an hour?" "Your interviewer just cut your budget in half, what goes?" A memorized answer shatters on the second follow-up. Real understanding bends and keeps going.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I've sat on both sides of this table, and the tell is always the same. Candidates who memorized answers speak in components. Candidates who understand systems speak in consequences.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prep for the interrogation, not the diagram
&lt;/h2&gt;

&lt;p&gt;The practical shift is this: spend less time collecting architectures and more time defending them. Four drills that actually build the muscle.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Write the failure mode before the feature.&lt;/strong&gt; For every design you study, force yourself to answer "what pages someone at 3 a.m.?" If you can't name the first thing that breaks under load, you don't understand the design, you've just seen it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Argue for the boring option.&lt;/strong&gt; Take any design that reaches for Kafka, Cassandra, or a service mesh, and write a straight-faced defense of Postgres, a cron job, and a monolith. Half the time the boring version wins, and knowing precisely when it stops winning is the whole skill. Interviewers light up when a candidate says "a single Postgres instance handles this until roughly X, and here's the migration path when we get there."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Attach numbers to everything.&lt;/strong&gt; Vague designs hide weak reasoning. Back-of-envelope math exposes it, in a good way:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Notification service, rough sizing:
  50M users x 5 notifications/day = 250M/day
  250M / 86,400s ≈ 2,900/sec average
  Morning peak at ~5x average    ≈ 15,000/sec
  ~1 KB payload → ~15 MB/s peak write throughput

Conclusion: one well-tuned queue and a modest worker pool.
Sharding talk at this stage is theater.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Thirty seconds of arithmetic like this does more for your credibility than ten minutes of boxes and arrows, because it shows you sized the problem before you solved it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Practice cutting scope out loud.&lt;/strong&gt; Interviewers love changing constraints mid-answer. Rehearse the sentence structure: "With half the timeline, I'd drop X, keep Y, and accept Z as a known risk." Naming the risk you're accepting is what separates a senior answer from a defensive one.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhgprga4f3llmuxj1na2b.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhgprga4f3llmuxj1na2b.jpg" alt="An engineer gesturing toward a system design diagram sketched on a glass whiteboard during an interview." width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  A weak answer and a strong one, side by side
&lt;/h2&gt;

&lt;p&gt;Question: "Your notification service needs to handle 10x traffic next quarter. What do you do?"&lt;/p&gt;

&lt;p&gt;Weak answer, the one a model would give: "I'd introduce Kafka for durability, add a Redis cache, shard the database by user ID, and scale the workers horizontally." Every word is defensible in isolation. It's also a list of ingredients with no recipe, and the first follow-up ("which of those do you do first, and why?") kills it.&lt;/p&gt;

&lt;p&gt;Strong answer: "First I'd find the current bottleneck, because 10x on paper is usually 10x on one component. If it's write throughput on the notifications table, I'd batch inserts and move fan-out to a queue before touching the schema. Sharding is the last resort here since it complicates every read path, and at 15k/sec peak we're likely one order of magnitude away from needing it. The thing I'd watch after the change is queue lag, because a silent hour of backlog means users get last night's alerts at 9 a.m., which for notifications is worse than dropping them."&lt;/p&gt;

&lt;p&gt;Notice what the strong answer contains that the weak one doesn't. A diagnosis before a prescription. An ordering. A stated reason to avoid a popular pattern. A specific, user-visible failure mode. None of that comes from memorizing designs. All of it comes from rehearsing the defense.&lt;/p&gt;

&lt;h2&gt;
  
  
  Make the AI your sparring partner, not your script
&lt;/h2&gt;

&lt;p&gt;The irony is that the tool eating the coding screen is the best design coach you'll ever get, if you flip its role. Don't ask it for the answer to "design a URL shortener." Give it your design and this instruction: "You are a skeptical staff engineer. Find the three weakest decisions here and interrogate me on each until I concede or convince you." Then answer out loud, in real sentences, the way you'd have to in the room. Ten sessions of that beats a hundred passive read-throughs of architecture write-ups.&lt;/p&gt;

&lt;p&gt;One honest caveat from my side of the fence: none of this matters if you never reach the design round, and getting there still runs through a resume that survives a recruiter's seven-second scan. I build Roleframe, so I'm biased, but that's the part I work on: &lt;a href="https://www.roleframe.ai" rel="noopener noreferrer"&gt;paste a job posting and it tailors your resume to that specific role and builds interview prep from your actual experience&lt;/a&gt;, so the prep hours go into defending trade-offs instead of rewriting bullets.&lt;/p&gt;

&lt;h2&gt;
  
  
  The moat is judgment, expressed under pressure
&lt;/h2&gt;

&lt;p&gt;AI compressed the value of knowing things. It hasn't touched the value of deciding things and standing behind the decision while someone pokes holes in it. That's what a system design interview measures, and it's the one round where your ten years, or your two hard years, of actually running systems shows up in a way no tool can fake.&lt;/p&gt;

&lt;p&gt;Start this week with something you've genuinely operated, even a small service. Write down three decisions it embodies, one number that justifies each, and the failure mode each one accepts. Then defend all three out loud to the harshest interviewer you can find, human or otherwise. That's the prep that compounds.&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>interview</category>
      <category>career</category>
      <category>ai</category>
    </item>
    <item>
      <title>The junior pipeline is broken. A job application tracker is your only defense.</title>
      <dc:creator>Larbi Sahli</dc:creator>
      <pubDate>Sun, 02 Aug 2026 13:28:48 +0000</pubDate>
      <link>https://dev.to/larbisahli_/the-junior-pipeline-is-broken-a-job-application-tracker-is-your-only-defense-5fmo</link>
      <guid>https://dev.to/larbisahli_/the-junior-pipeline-is-broken-a-job-application-tracker-is-your-only-defense-5fmo</guid>
      <description>&lt;p&gt;Junior engineers tell me the same story on repeat: 150, sometimes 200+ applications before anything sticks. Five years ago, 30 thoughtful applications would land a junior a handful of phone screens. Then AI made it trivial for everyone to apply everywhere, companies responded with harder filters, and entry-level postings started drawing four-digit applicant counts within days.&lt;/p&gt;

&lt;p&gt;You can be angry about that. I am, and I read resumes for a living. But anger doesn't change the math you're operating under, and the math says this: when a process requires 150+ attempts, memory and a messy spreadsheet stop being tools and start being liabilities.&lt;/p&gt;

&lt;p&gt;Sales teams solved this exact problem decades ago. They call it a CRM, a customer relationship management system, and it exists because no human can run a 200-opportunity pipeline in their head. Your job search is now a 200-opportunity pipeline. Here's how to build a job application tracker that works like one.&lt;/p&gt;

&lt;h2&gt;
  
  
  Your spreadsheet dies around application 40
&lt;/h2&gt;

&lt;p&gt;A flat spreadsheet with columns for company, role, and "status" works fine for a dozen applications. Somewhere around 40, three things break.&lt;/p&gt;

&lt;p&gt;First, you lose the timeline. "Status: Interviewing" tells you nothing about whether the recruiter went quiet six days ago, which is exactly when a polite nudge would have helped.&lt;/p&gt;

&lt;p&gt;Second, you lose the feedback loop. If you can't answer "what's my response rate on referrals versus job boards," you can't reallocate your hours toward what's working. You just keep spraying.&lt;/p&gt;

&lt;p&gt;Third, you lose the artifacts. When a recruiter calls about an application from three weeks ago, you need the exact resume PDF you sent them and the posting text, which by then has usually been taken down. A spreadsheet cell that says "applied ✓" gives you neither, and walking into a phone screen without knowing what the other person is reading is how juniors flunk screens they should pass.&lt;/p&gt;

&lt;p&gt;A sales rep would never tolerate any of these. Their CRM records every stage transition with a date, attributes every deal to a source, and attaches every document sent. Steal all three ideas.&lt;/p&gt;

&lt;h2&gt;
  
  
  Stages, not statuses
&lt;/h2&gt;

&lt;p&gt;The core shift is from a status field you overwrite to a pipeline of stages you move through. A reasonable pipeline for a junior engineering search:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Sourced&lt;/strong&gt; – you found the posting, haven't applied yet&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Applied&lt;/strong&gt; – application submitted, resume version recorded&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Screen&lt;/strong&gt; – recruiter call or async screen scheduled&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Technical&lt;/strong&gt; – coding challenge, take-home, or technical interview&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Onsite&lt;/strong&gt; – final loop&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Offer&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rejected&lt;/strong&gt; or &lt;strong&gt;Ghosted&lt;/strong&gt; – both are terminal, and both are data&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Two rules make this work. Every transition gets a timestamp, because the timestamps are what power your conversion metrics and your follow-up timing. And &lt;strong&gt;Ghosted&lt;/strong&gt; is a real stage you assign deliberately, not a purgatory you leave things in. My rule: no response 21 days after your last touch means ghosted. Close it, log it, reclaim the mental space. You can always reopen if they resurface.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F25bez5gv8ti1pckhwzwa.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F25bez5gv8ti1pckhwzwa.jpg" alt="A young job seeker focused on organizing their job applications with a notebook and coffee in a sunlit apartment." width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The schema
&lt;/h2&gt;

&lt;p&gt;You can build this in Notion or Airtable, but I'll show it as SQLite because half of you will enjoy that more, and because writing the schema forces you to decide what you actually track.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;applications&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="n"&gt;id&lt;/span&gt;              &lt;span class="nb"&gt;INTEGER&lt;/span&gt; &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;company&lt;/span&gt;         &lt;span class="nb"&gt;TEXT&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="k"&gt;role&lt;/span&gt;            &lt;span class="nb"&gt;TEXT&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;posting_url&lt;/span&gt;     &lt;span class="nb"&gt;TEXT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;posting_text&lt;/span&gt;    &lt;span class="nb"&gt;TEXT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;      &lt;span class="c1"&gt;-- paste it; postings vanish&lt;/span&gt;
  &lt;span class="n"&gt;posted_at&lt;/span&gt;       &lt;span class="nb"&gt;DATE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;      &lt;span class="c1"&gt;-- how fresh was it when you applied?&lt;/span&gt;
  &lt;span class="k"&gt;source&lt;/span&gt;          &lt;span class="nb"&gt;TEXT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;      &lt;span class="c1"&gt;-- 'referral', 'linkedin', 'board', 'cold'&lt;/span&gt;
  &lt;span class="n"&gt;stack_match&lt;/span&gt;     &lt;span class="nb"&gt;INTEGER&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;   &lt;span class="c1"&gt;-- 0-100: % of required skills you have&lt;/span&gt;
  &lt;span class="n"&gt;resume_version&lt;/span&gt;  &lt;span class="nb"&gt;TEXT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;      &lt;span class="c1"&gt;-- filename of the exact PDF you sent&lt;/span&gt;
  &lt;span class="n"&gt;stage&lt;/span&gt;           &lt;span class="nb"&gt;TEXT&lt;/span&gt; &lt;span class="k"&gt;DEFAULT&lt;/span&gt; &lt;span class="s1"&gt;'sourced'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;applied_at&lt;/span&gt;      &lt;span class="nb"&gt;DATE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;stage_changed_at&lt;/span&gt; &lt;span class="nb"&gt;DATE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;last_touch_at&lt;/span&gt;   &lt;span class="nb"&gt;DATE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;      &lt;span class="c1"&gt;-- last time YOU did something&lt;/span&gt;
  &lt;span class="n"&gt;next_action&lt;/span&gt;     &lt;span class="nb"&gt;TEXT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;next_action_at&lt;/span&gt;  &lt;span class="nb"&gt;DATE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;notes&lt;/span&gt;           &lt;span class="nb"&gt;TEXT&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;events&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="n"&gt;id&lt;/span&gt;         &lt;span class="nb"&gt;INTEGER&lt;/span&gt; &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;app_id&lt;/span&gt;     &lt;span class="nb"&gt;INTEGER&lt;/span&gt; &lt;span class="k"&gt;REFERENCES&lt;/span&gt; &lt;span class="n"&gt;applications&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="n"&gt;happened_at&lt;/span&gt; &lt;span class="nb"&gt;DATE&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;kind&lt;/span&gt;       &lt;span class="nb"&gt;TEXT&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="c1"&gt;-- 'applied', 'followed_up', 'screen', ...&lt;/span&gt;
  &lt;span class="n"&gt;notes&lt;/span&gt;      &lt;span class="nb"&gt;TEXT&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Three fields deserve a closer look because they're the ones spreadsheets never have.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;posted_at&lt;/code&gt; matters because freshness matters. An application submitted the day a role goes live competes with dozens of candidates. The same application two weeks later competes with hundreds, many already in the pipeline. Track the gap between &lt;code&gt;posted_at&lt;/code&gt; and &lt;code&gt;applied_at&lt;/code&gt; and you'll see it in your own response rates.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;stack_match&lt;/code&gt; is your honest estimate, 0 to 100, of how much of the required stack you cover. Score it when you source the role, before you apply. It becomes your best predictor, as you'll see below.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;resume_version&lt;/code&gt; should point to the exact PDF you submitted. PDF specifically, because it locks your formatting and it's what you want a hiring manager opening. Name the files something like &lt;code&gt;resume-backend-acme-2025-06.pdf&lt;/code&gt; so the tracker entry and the artifact can't drift apart.&lt;/p&gt;

&lt;h2&gt;
  
  
  Three numbers that change how you apply
&lt;/h2&gt;

&lt;p&gt;The tracker earns its keep the first time you query it. Start with conversion by source:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;source&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;applied&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="k"&gt;SUM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stage&lt;/span&gt; &lt;span class="k"&gt;IN&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'screen'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;'technical'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;'onsite'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;'offer'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;screens&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="n"&gt;ROUND&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;SUM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stage&lt;/span&gt; &lt;span class="k"&gt;IN&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'screen'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;'technical'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;'onsite'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;'offer'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
             &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;screen_rate&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;applications&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;stage&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="s1"&gt;'sourced'&lt;/span&gt;
&lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="k"&gt;source&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;screen_rate&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When a junior runs this for the first time, the usual discovery is that one channel, often referrals or direct applications to smaller companies, converts several times better than the job boards eating 90% of their hours. That single query justifies the whole system.&lt;/p&gt;

&lt;p&gt;Second, screen rate by &lt;code&gt;stack_match&lt;/code&gt; bucket. If roles where you match 80%+ of the stack convert at triple the rate of roles below 50%, and for most juniors they do, then every hour spent on sub-50 applications is an hour stolen from outreach on the good ones. The tracker turns a vague feeling of "nothing's working" into a specific instruction: raise your floor.&lt;/p&gt;

&lt;p&gt;Third, stage-to-stage conversion, which tells you where to spend improvement effort. Lots of applications but no screens is a resume problem. Screens that never become technicals is a story problem, so drill your "walk me through your background" answer. Technicals that never become onsites means practice under time pressure. Without stage data you're guessing at which of these is broken, and juniors reliably guess wrong, grinding LeetCode when the actual leak is upstream at the resume.&lt;/p&gt;

&lt;p&gt;The resume leak is worth a specific word, because it interacts with the freshness point. The fix is a resume tailored to each posting, submitted while the posting is days old rather than weeks. Doing that by hand at 150-application volume is brutal, which is the problem I started a company around. I build Roleframe, so I'm biased, but this workflow is what it does: &lt;a href="https://www.roleframe.ai" rel="noopener noreferrer"&gt;track the jobs you're applying to, paste a posting, and get a resume tailored to it in seconds&lt;/a&gt;, with the exported PDF recorded against the application. If you'd rather stay in SQLite and tailor by hand, everything else in this article still stands.&lt;/p&gt;

&lt;h2&gt;
  
  
  Follow-up is where the compounding happens
&lt;/h2&gt;

&lt;p&gt;Sales reps know most deals close on the follow-up, and most candidates never send one. That asymmetry is free advantage for anyone willing to be politely persistent.&lt;/p&gt;

&lt;p&gt;A cadence that has served the engineers I've watched run disciplined searches:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Day 0:&lt;/strong&gt; apply, then find one relevant human at the company (recruiter, engineering manager, someone on the team) and send a two-sentence note saying you applied and why the role fits.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Day 7:&lt;/strong&gt; if silence, one short follow-up. New information helps: a relevant project you shipped, a specific line from the posting you're a match for.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Day 14:&lt;/strong&gt; one final nudge.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Day 21:&lt;/strong&gt; mark it ghosted and move on without guilt.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The &lt;code&gt;next_action&lt;/code&gt; and &lt;code&gt;next_action_at&lt;/code&gt; fields exist so this runs without willpower. Each morning, query for actions due today:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;company&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;role&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;next_action&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;applications&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;next_action_at&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="nb"&gt;date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'now'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;stage&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;IN&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'rejected'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;'ghosted'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;'offer'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;next_action_at&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That query is your job-search standup. Ten minutes, every day, and nothing falls through the cracks. The candidate who follows up on day 7 isn't more qualified than the one who doesn't. They're just the one the recruiter remembers when the shortlist gets made.&lt;/p&gt;

&lt;h2&gt;
  
  
  Set it up tonight
&lt;/h2&gt;

&lt;p&gt;The junior market isn't going back to 2019. The volume is the volume, and the engineers getting through aren't the ones sending the most applications. They're the ones running the tightest process: fresh postings, tailored PDFs, tracked stages, disciplined follow-up, and a weekly look at their own conversion data to see what to fix next.&lt;/p&gt;

&lt;p&gt;All of that starts with the tracker. Tonight, create the table, or the Notion board if that's more your speed. Backfill your last ten applications from your email, including the ones that went nowhere, because the failures are where the signal is. Then run the source query in two weeks and let your own data tell you where your next 40 hours should go.&lt;/p&gt;

&lt;p&gt;You can't control how many people apply to the role you want. You can control being early, being tailored, and being the applicant who followed up. That turns out to be most of the fight.&lt;/p&gt;

</description>
      <category>career</category>
      <category>jobsearch</category>
      <category>productivity</category>
      <category>programming</category>
    </item>
    <item>
      <title>How Applicant Tracking Systems Actually Score Your Tech Stack</title>
      <dc:creator>Larbi Sahli</dc:creator>
      <pubDate>Fri, 31 Jul 2026 21:38:08 +0000</pubDate>
      <link>https://dev.to/larbisahli_/how-applicant-tracking-systems-actually-score-your-tech-stack-564c</link>
      <guid>https://dev.to/larbisahli_/how-applicant-tracking-systems-actually-score-your-tech-stack-564c</guid>
      <description>&lt;p&gt;Stuffing "React, Node.js, TypeScript, AWS, Docker, Kubernetes" into your resume summary does almost nothing for you. I know because I build resume software for a living, which means I've spent an unreasonable amount of time studying how resumes get parsed, stored, and queried on the other side of the apply button. The mechanics are closer to a database problem than a writing problem, and once you see the schema, the fix is obvious.&lt;/p&gt;

&lt;p&gt;Here's the short version: an applicant tracking system (ATS) doesn't score your resume as a wall of text. It converts it into a structured record, and recruiters query that record. If your skills aren't attached to the right structure, you don't rank low. You don't appear in the result set at all.&lt;/p&gt;

&lt;h2&gt;
  
  
  Your resume becomes a database record, not a document
&lt;/h2&gt;

&lt;p&gt;The moment your PDF hits an ATS, a parsing pipeline runs. It extracts the text layer, classifies sections (summary, experience, education, skills), then pulls out entities: employers, job titles, date ranges, degrees, and skills. Those entities get normalized against a skills taxonomy, so "JS", "Javascript", and "ECMAScript" usually collapse into one canonical skill.&lt;/p&gt;

&lt;p&gt;What lands in the database looks roughly like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"work_history"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"employer"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Acme Corp"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Senior Software Engineer"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"start"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2021-03"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"end"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"skills_in_context"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"React"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"TypeScript"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"GraphQL"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"PostgreSQL"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"skills"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"React"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"estimated_years"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;4.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"last_used"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"current"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"roles_mentioned_in"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice what's missing from that record: your summary paragraph. Most systems treat the summary as low-signal text. A skill that appears only there gets flagged as "claimed" with no duration, no recency, and no role attached. That's why keyword stuffing the top of your resume is wasted effort. You're writing to a field the query barely touches.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0x1f2gvq9evqq117hkvn.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0x1f2gvq9evqq117hkvn.jpg" alt="A hiring manager and recruiter collaborating at a desk, reviewing a candidate's technical profile on a laptop screen." width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The scoring unit is skill + years + context
&lt;/h2&gt;

&lt;p&gt;How does an ATS know you have "5+ years of React"? You never wrote that number anywhere. It computes it.&lt;/p&gt;

&lt;p&gt;The parser attaches each skill to the job entries where it appears, then sums the date ranges of those jobs. Mention React in a bullet under a role you held from 2019 to 2023, and React inherits four years. Mention it again under your current role and the counter keeps running, with &lt;code&gt;last_used: current&lt;/code&gt; as a bonus signal.&lt;/p&gt;

&lt;p&gt;This is the single most useful thing to understand about applicant tracking system keywords: a keyword's value comes from what it's attached to. The same word carries different weight depending on where it lives.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;In a bullet under a dated job:&lt;/strong&gt; full value. Duration, recency, and a title for context.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;In a skills section:&lt;/strong&gt; the skill exists in your record, but with weak or no duration data.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;In the summary only:&lt;/strong&gt; close to zero. Claimed, unverified, unattached.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So the dev who lists Kubernetes in a skills grid loses to the dev who wrote "migrated 30 services to Kubernetes" under a two-year role, even if the first one knows it better. The database can't see what you know. It can only see what you attached.&lt;/p&gt;

&lt;h2&gt;
  
  
  What a recruiter query actually looks like
&lt;/h2&gt;

&lt;p&gt;The "ATS auto-rejected my resume" story is mostly a myth. In the pipelines I've seen, the system rarely rejects anyone on its own. What happens instead is quieter and worse: a recruiter runs a search, and you're not in the results.&lt;/p&gt;

&lt;p&gt;A typical sourcing query looks something like this, syntax varying by vendor:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(title:"frontend engineer" OR title:"front end" OR title:"react developer")
AND skill:React AND skill:TypeScript
AND skill_years:React &amp;gt;= 4
AND applied_within: 14 days
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Three things fall out of that query shape.&lt;/p&gt;

&lt;p&gt;First, filters are binary. If your React years computed to 3.8 because the parser couldn't attach it to your first job, you're out, and no human ever saw your name. Second, results are ranked, usually by recency of the skill, how many distinct roles it appears in, and how closely your current title matches the search. Third, look at that last line: recruiters routinely scope searches to recent applicants because postings collect hundreds of resumes fast. Applying in the first days of a posting isn't superstition. It's a WHERE clause.&lt;/p&gt;

&lt;h2&gt;
  
  
  Structure your experience section for the parser
&lt;/h2&gt;

&lt;p&gt;Everything above points to one conclusion: your experience section is the table that matters, and each bullet is a row. Write it that way.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Name the technology inside the bullet where you used it.&lt;/strong&gt; Compare:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Before: "Worked on frontend features across the platform."&lt;/p&gt;

&lt;p&gt;After: "Built the checkout flow in React and TypeScript, backed by a GraphQL layer over PostgreSQL, cutting checkout errors roughly in half."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The first bullet contributes nothing to your record. The second attaches four skills to a dated role, with an outcome a human recruiter can read in the same seven seconds.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use canonical names.&lt;/strong&gt; "Modern component frameworks" matches nothing. "React" matches React. When a tool has common variants, taxonomies usually handle it, but don't gamble on obscure ones: write "PostgreSQL" at least once even if you say "Postgres" elsewhere, and "Amazon Web Services (AWS)" on first use.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Keep each job entry structurally boring.&lt;/strong&gt; Employer, title, and dates on predictable lines, consistent date formats, bullets underneath. Parsers are good now, but two-column layouts, tables, and icon-based skill bars still scramble text extraction order. Boring structure is a feature.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Treat the skills section as an index, not the content.&lt;/strong&gt; It helps normalization and catches keywords you couldn't fit into bullets. It proves nothing on its own.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Export as PDF with a real text layer.&lt;/strong&gt; A clean PDF preserves your formatting exactly and parses reliably. Skip screenshots-as-PDF and skip .docx unless a specific employer explicitly demands it.&lt;/p&gt;

&lt;p&gt;The tedious part is that the right keywords change per posting. One React role leads with testing, another with performance, another with GraphQL, and matching your bullets to each one by hand takes an evening per application. I build Roleframe, so I'm biased, but this is exactly the problem it exists for: &lt;a href="https://www.roleframe.ai/go/MFb9WoTE" rel="noopener noreferrer"&gt;paste a job posting&lt;/a&gt;, and it extracts the keywords that role's filters will scan for, shows which ones your resume already covers in context, and rewrites the bullets with your approval. By hand or with a tool, the principle is the same. Match the posting's exact vocabulary inside dated experience, never in a stuffed summary.&lt;/p&gt;

&lt;h2&gt;
  
  
  What AI matching changes, and what it doesn't
&lt;/h2&gt;

&lt;p&gt;Newer platforms layer semantic matching on top of keyword search, so "built a REST API in Express" can partially match a posting that says "Node.js backend services." That's real progress, and it softens the exact-vocabulary problem at the ranking stage.&lt;/p&gt;

&lt;p&gt;It doesn't soften the filtering stage. Hard filters on computed years, titles, and normalized skills still run first, on the structured record, before any semantic ranking sees your resume. A fuzzy match can move you from position 40 to position 12. It cannot put you inside a result set a boolean filter already excluded you from.&lt;/p&gt;

&lt;p&gt;So the playbook holds regardless of how smart the matching gets. Attach every skill you want credit for to a dated role with a concrete outcome. Mirror the posting's exact terms in those bullets. Apply while the posting is fresh, because recency is a filter too. You're not writing prose for a robot. You're writing rows for a query, and now you know the schema.&lt;/p&gt;

</description>
      <category>career</category>
      <category>webdev</category>
      <category>jobsearch</category>
      <category>softwareengineering</category>
    </item>
    <item>
      <title>How to Write a Career Change Resume That Actually Gets Interviews</title>
      <dc:creator>Larbi Sahli</dc:creator>
      <pubDate>Mon, 27 Jul 2026 21:57:12 +0000</pubDate>
      <link>https://dev.to/larbisahli_/how-to-write-a-career-change-resume-that-actually-gets-interviews-217g</link>
      <guid>https://dev.to/larbisahli_/how-to-write-a-career-change-resume-that-actually-gets-interviews-217g</guid>
      <description>&lt;p&gt;A lot of people reading dev.to didn't start in software. Bootcamp grads, teachers, nurses, retail managers, marketers who taught themselves SQL. And plenty of devs are pivoting the other way, into product, data, or DevRel. I built Roleframe around per-job resume tailoring, and career switchers are the group I see struggle most, because their job titles actively work against them in every screening system.&lt;/p&gt;

&lt;p&gt;I wrote this guide because the standard advice for switchers is mostly wrong. The "functional resume that hides your dates" trick gets you flagged by recruiters. The clever objective line gets skimmed past. What actually works is more mechanical and more honest: lead with the destination, prove relevance with real results, and match the exact vocabulary the new field's screening software is scoring against.&lt;/p&gt;

&lt;p&gt;Here's the full playbook, section by section, with the specific moves that get switchers interviews instead of silence.&lt;/p&gt;

&lt;h2&gt;
  
  
  The core problem with career change resumes
&lt;/h2&gt;

&lt;p&gt;Your resume gets judged twice, and both judges are skeptical of switchers. First an applicant tracking system (ATS), the software companies use to store and search applications, scores you against the job's keywords. Then a human recruiter spends a few seconds deciding whether you look like a fit.&lt;/p&gt;

&lt;p&gt;A career changer fails both by default. The ATS ranks you low because your resume is full of the previous industry's vocabulary, not the new one's. The recruiter reads a title that doesn't match the role and assumes you're a stretch. Neither one is trying to be unfair. They're both filtering for obvious relevance, and a raw chronological resume from your old field doesn't signal it.&lt;/p&gt;

&lt;p&gt;So the whole task comes down to one thing: manufacturing obvious relevance. You do that by reframing what you've done in the language of where you're going, and by putting the most relevant proof at the top where both judges will actually see it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why the wrong format quietly sinks you
&lt;/h3&gt;

&lt;p&gt;Many switchers reach for a "functional" resume that hides dates and job titles behind a wall of skills. Recruiters distrust it instantly, because it reads like you're concealing something. It also confuses the ATS, which expects dated work history it can parse. Think of it like a file the parser can't deserialize: the content might be great, but nothing downstream ever sees it.&lt;/p&gt;

&lt;p&gt;The format that works is the combination (hybrid) format: a targeted summary and a skills section up top, then a normal reverse-chronological work history underneath, reframed for relevance. The top third sells your fit for the new field. The bottom keeps the structure recruiters and software trust.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why you need role workspaces, not one all-purpose resume
&lt;/h2&gt;

&lt;p&gt;Career changers rarely target a single job title. You might be weighing frontend developer against data analyst against product manager, or moving from teaching into instructional design, developer education, and QA at once. Each of those needs a genuinely different resume, because each field prizes different keywords and different proof.&lt;/p&gt;

&lt;p&gt;The common mistake is keeping one master resume and rewriting it over and over for each direction. Every rewrite risks breaking the version that was working, and you lose track of which draft went where. It's the resume equivalent of editing production directly with no version control.&lt;/p&gt;

&lt;p&gt;A cleaner system is to keep a separate base resume per target role, then spin off a tailored version for each specific job. That's exactly what Roleframe is built around: role workspaces hold one master resume per direction you're exploring, and each application gets its own tailored copy without touching the master.&lt;/p&gt;

&lt;h2&gt;
  
  
  Identifying and highlighting transferable skills
&lt;/h2&gt;

&lt;p&gt;Transferable skills are the abilities that carry across industries: managing stakeholders, analyzing data, running projects, coaching people, writing clearly. They're the backbone of any career change resume, because they let you claim relevance you can't get from your job titles.&lt;/p&gt;

&lt;p&gt;Start by pulling apart your old roles into skills, not duties. A teacher doesn't just "teach." She manages a room of thirty, builds curriculum on a deadline, tracks performance data, and communicates with difficult stakeholders (parents). Each of those maps onto a corporate job. The reframing work is naming the underlying skill instead of the industry-specific task.&lt;/p&gt;

&lt;h3&gt;
  
  
  How to find which skills actually matter
&lt;/h3&gt;

&lt;p&gt;Don't guess at what the new field values. Pull up three to five real job postings for your target role and read them side by side. Note the skills, tools, and phrases that repeat. The U.S. Department of Labor's O*NET occupation database is another good source for the core competencies of a specific job. The words that show up again and again are the skills your resume needs to prove.&lt;/p&gt;

&lt;p&gt;Then match your history to that list. For each recurring skill, find one concrete thing you've done that demonstrates it. That pairing, target skill plus your proof, becomes the raw material for your skills section and your bullets.&lt;/p&gt;

&lt;h3&gt;
  
  
  Group skills the way the new industry does
&lt;/h3&gt;

&lt;p&gt;Recruiters and ATS searches are increasingly skills-driven, so a labeled skills section earns its place at the top. Organize it into categories the target field uses, not generic buckets. A data analyst pivot might use headers like "Data &amp;amp; Analytics," "SQL &amp;amp; Reporting," and "Stakeholder Communication." Name real tools where you've genuinely used them: SQL, Figma, Salesforce, Asana, Excel.&lt;/p&gt;

&lt;p&gt;Where you can, add a short evidence line under a skill rather than listing it bare. "Stakeholder Management: aligned five department heads on a shared reporting standard" beats the word "communication" sitting alone. Evidence turns a keyword into a claim you've backed up.&lt;/p&gt;

&lt;h2&gt;
  
  
  Structuring your experience section for a pivot
&lt;/h2&gt;

&lt;p&gt;Your experience section has to do double duty: satisfy the ATS with real dated roles, and convince a human that the work is relevant. The trick is reframing each bullet around outcomes that matter in the new field, not tasks that mattered in the old one.&lt;/p&gt;

&lt;p&gt;Lead every bullet with a measurable result, then add brief context. This is a STAR-style approach compressed into one line: the achievement first, the situation second. "Cut support ticket volume 18% by redesigning the onboarding flow" reads as a business outcome any industry understands. "Responsible for handling customer inquiries" reads as a task nobody remembers.&lt;/p&gt;

&lt;h3&gt;
  
  
  Reframe the work, don't invent it
&lt;/h3&gt;

&lt;p&gt;Reframing means changing the language and emphasis, never the facts. If you managed a retail team and you're targeting operations, describe it as scheduling, inventory forecasting, and shrinkage reduction, because those are operations skills. Same job, different lens. You're translating your experience into the vocabulary of the reader.&lt;/p&gt;

&lt;p&gt;Quantify wherever you honestly can. Percentages, dollar amounts, headcounts, time saved, volume handled. Numbers are industry-neutral proof, and they pull a recruiter's eye toward substance instead of your unfamiliar job title.&lt;/p&gt;

&lt;h3&gt;
  
  
  Use a "relevant experience" section to move recent proof up
&lt;/h3&gt;

&lt;p&gt;If your most relevant work isn't your most recent paid job, create a section that surfaces it. Many switchers add a Relevant Experience or Relevant Projects block above their standard work history. Put your bootcamp project, freelance gig, open-source contributions, volunteer role, or side work there, so the first thing a reader sees is recent, concrete practice in the new field.&lt;/p&gt;

&lt;p&gt;This directly answers the "no experience" version of the pivot. You almost always have more relevant experience than you think, it's just scattered across unpaid or informal work. If you're switching into software, this is exactly where a well-documented portfolio project carries the most weight.&lt;/p&gt;

&lt;h3&gt;
  
  
  Feature training and credentials near the top
&lt;/h3&gt;

&lt;p&gt;Recent learning signals you're serious about the switch, so don't bury it at the bottom. If you've finished a Google Career Certificate, a Coursera or edX program, an industry micro-cert, or tool-specific training, place it high enough to be seen in the first pass. For a career changer, a fresh, relevant credential often carries more weight than a decade-old degree in the old field.&lt;/p&gt;

&lt;h2&gt;
  
  
  Writing a summary that bridges the gap
&lt;/h2&gt;

&lt;p&gt;The professional summary is where you win or lose the pivot, because it's the first thing read and it sets the frame for everything below. Name your target role directly. Write "Data Analyst" or "Frontend Developer," not "marketing professional seeking to transition into tech." You want to read as someone who already operates in the new space, not someone hoping to be let in.&lt;/p&gt;

&lt;p&gt;Cut the words "aspiring" and "transitioning." They plant doubt. Present-tense confidence backed by transferable achievements does the opposite.&lt;/p&gt;

&lt;h3&gt;
  
  
  The three-part summary formula
&lt;/h3&gt;

&lt;p&gt;A strong career transition summary makes three moves in three to four sentences:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Who you are in the target role, stated plainly with your relevant strengths.&lt;/li&gt;
&lt;li&gt;Two or three transferable proof points, ideally quantified, that show you've already done the work in a different setting.&lt;/li&gt;
&lt;li&gt;What you're ready to deliver next, tied to the kind of role you're applying for.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Here's the pattern in action for a teacher moving into corporate training: "Learning and development specialist with seven years designing and delivering instruction to groups of 30+. Built a curriculum adopted district-wide and raised assessment scores 22% in one year. Now focused on scaling employee onboarding and skills programs for a growing team." No apology, no "aspiring," just a claim with evidence.&lt;/p&gt;

&lt;h3&gt;
  
  
  Add one line of bridge content
&lt;/h3&gt;

&lt;p&gt;Recruiters do wonder why you're switching, so answer it briefly instead of leaving them to guess. One sentence is enough on the resume: what draws you to the field, which transferable strength proves your fit, and any training you've completed. Save the fuller story for your cover letter, where a short paragraph can explain the move without cluttering the resume. Roleframe generates a job-specific cover letter to pair with each tailored resume, which is the natural place to carry that narrative.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tailoring to the new industry's ATS keywords
&lt;/h2&gt;

&lt;p&gt;This is where career changers lose the most interviews without ever knowing it. Modern ATS and AI screeners score your resume on how closely its language matches the job description. When you're switching fields, your resume is written in your old industry's terms, so it scores low on the exact keywords the new role searches for. You never hear back, and it looks like rejection when it's really a language mismatch.&lt;/p&gt;

&lt;p&gt;Exact-match matters more than people expect. If the posting says "stakeholder management" and your resume says "working with clients," a keyword-based screen may not connect them. If it asks for "SQL" and you wrote "database querying," you can miss the filter. The screen does string matching, not semantic search. For switchers with no title match to fall back on, mirroring the posting's precise terminology is the thing that gets you seen.&lt;/p&gt;

&lt;h3&gt;
  
  
  How to match keywords without stuffing
&lt;/h3&gt;

&lt;p&gt;Work from the same three to five postings you used to map your skills. Extract the recurring hard skills, tools, and phrases, then place them where they belong: in your summary, your skills section, and inside real achievement bullets. The goal is genuine coverage, not a keyword dump. A skill that appears in a real accomplishment reads as true; a skill stuffed into a list at the bottom reads as filler and a recruiter sees through it.&lt;/p&gt;

&lt;p&gt;Doing this by hand for every application is slow, and speed matters for switchers. This is the part I automated with Roleframe: paste a job posting and it tailors your keywords, section order, and bullets for that specific job in seconds, so each application matches the language the screener is scoring against.&lt;/p&gt;

&lt;h3&gt;
  
  
  Keep the layout ATS-safe
&lt;/h3&gt;

&lt;p&gt;All the keyword work fails if the software can't parse your file. Use a clean single-column layout, standard fonts like Calibri or Helvetica, and no text boxes, graphics, or multi-column tricks that scramble parsing. Keep it to one page for an early-career pivot, up to two for a senior professional with a long, reframed history.&lt;/p&gt;

&lt;p&gt;Save and submit as a PDF. It preserves your formatting across every device and is what recruiters expect. Only send a .docx if a specific employer or ATS explicitly asks for it, and even then, PDF is your default. Roleframe exports a clean, ATS-friendly PDF that matches the editor exactly, so what you approve on screen is what the recruiter opens.&lt;/p&gt;

&lt;h2&gt;
  
  
  Apply fast, before the pipeline fills
&lt;/h2&gt;

&lt;p&gt;Timing decides more outcomes than people admit. Many roles collect most of their strong applicants in the first few days, and recruiters often start reviewing before the posting closes. Apply late and you're competing for attention that's already spoken for, no matter how good your resume is.&lt;/p&gt;

&lt;p&gt;This is the hidden tax on career changers. Because your resume needs more tailoring than a straightforward applicant's, the honest tailoring work can push your application past the window where it matters most. The answer isn't to skip tailoring and send something generic; a generic resume from a switcher gets filtered fast. The answer is to make tailoring fast enough that you're both relevant and early.&lt;/p&gt;

&lt;h2&gt;
  
  
  A quick reference: the resume rules people ask about
&lt;/h2&gt;

&lt;p&gt;A few shorthand "rules" circulate in resume advice. Here's what they mean and how they apply to a career change specifically.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Rule&lt;/th&gt;
&lt;th&gt;What it means&lt;/th&gt;
&lt;th&gt;Why it matters for a switcher&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;7-second rule&lt;/td&gt;
&lt;td&gt;Recruiters give a resume roughly a few seconds on first scan&lt;/td&gt;
&lt;td&gt;Your target role and best proof must sit in the top third, or the pivot is missed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3 C's&lt;/td&gt;
&lt;td&gt;Clear, concise, compelling&lt;/td&gt;
&lt;td&gt;A switcher's story fails if it's cluttered; clarity is what makes an unfamiliar path believable&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5 P's&lt;/td&gt;
&lt;td&gt;Positioning, presentation, proof, personalization, polish&lt;/td&gt;
&lt;td&gt;Positioning and personalization carry the most weight when you're changing fields&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Career change resume checklist
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Use a combination format: targeted summary and skills up top, dated work history below.&lt;/li&gt;
&lt;li&gt;Name your target role directly in the summary; drop "aspiring" and "transitioning."&lt;/li&gt;
&lt;li&gt;Mine three to five real job postings and O*NET for the exact skills and terms the field uses.&lt;/li&gt;
&lt;li&gt;Reframe each bullet as a quantified outcome, not an old-industry task.&lt;/li&gt;
&lt;li&gt;Add a Relevant Experience or Projects section to surface recent, aligned work.&lt;/li&gt;
&lt;li&gt;Feature recent credentials and training near the top for credibility.&lt;/li&gt;
&lt;li&gt;Match the posting's exact keywords in your summary, skills, and bullets.&lt;/li&gt;
&lt;li&gt;Keep the layout ATS-safe and export as a PDF.&lt;/li&gt;
&lt;li&gt;Tailor per job and apply while the posting is fresh.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The short version: a career change resume isn't about hiding where you came from. It's about translating what you did into the language of where you're going, backing it with numbers, and getting it in front of the recruiter before the pipeline fills. Do those three things and the mismatched job title stops being a dealbreaker.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://www.roleframe.ai/blog/how-to-write-career-change-resume?utm_source=devto&amp;amp;utm_medium=social&amp;amp;utm_campaign=how-to-write-career-change-resume" rel="noopener noreferrer"&gt;roleframe.ai&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>career</category>
      <category>softwareengineering</category>
      <category>careerchange</category>
    </item>
    <item>
      <title>Why Your AI Resume Sounds Generic (And How to Fix It)</title>
      <dc:creator>Larbi Sahli</dc:creator>
      <pubDate>Mon, 27 Jul 2026 21:44:10 +0000</pubDate>
      <link>https://dev.to/larbisahli_/why-your-ai-resume-sounds-generic-and-how-to-fix-it-3l7c</link>
      <guid>https://dev.to/larbisahli_/why-your-ai-resume-sounds-generic-and-how-to-fix-it-3l7c</guid>
      <description>&lt;p&gt;I'm Larbi, and I build Roleframe, an AI tool that tailors resumes to specific jobs. I spend a lot of time looking at what large language models (LLMs) produce when you ask them to "improve" a resume, and the output is almost always the same: &lt;code&gt;results-driven professional&lt;/code&gt;, &lt;code&gt;leveraged cross-functional teams&lt;/code&gt;, &lt;code&gt;orchestrated end-to-end solutions&lt;/code&gt;. If you've used ChatGPT on your own resume, you've seen it too.&lt;/p&gt;

&lt;p&gt;I wanted to write this for a developer audience because you already understand the machinery underneath the problem. This isn't magic or a mystery. It's next-token prediction, model routing, and prompt design. Once you see the resume through that lens, the fix becomes obvious and mechanical.&lt;/p&gt;

&lt;p&gt;What you'll get here: why cheap models default to generic phrasing, the three tells recruiters catch, why a single prompt can't tailor a resume properly, and a ten-minute audit you can run on any AI output before you send it. Let's get into it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The unlimited AI trap: why your resume reads like a robot
&lt;/h2&gt;

&lt;p&gt;Most "unlimited AI" resume builders have a math problem they don't advertise. If a tool promises endless rewrites for a flat monthly fee, it can't afford to run the best, most expensive models on every request. So it routes your resume to the cheapest model that produces passable text.&lt;/p&gt;

&lt;p&gt;Cheap models play it safe. When they're unsure what to say, they fall back on the highest-probability phrasing in their training data. That data is millions of existing resumes and job ads, so the model mirrors the average of all of them. The result is what recruiters call a resume monoculture: near-identical wording and structure no matter who the candidate is or what they actually did.&lt;/p&gt;

&lt;p&gt;You feel it as vagueness. Padded metrics, filler verbs, and summaries that describe a job title instead of a person. The tool isn't broken. It's doing exactly what a low-compute model does when nobody paid for anything better.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cheap models vs. frontier models: the hidden downgrade
&lt;/h2&gt;

&lt;p&gt;There's a real quality gap between the cheap models behind "unlimited" plans and the frontier models that cost more to run. The difference isn't grammar. Both write clean sentences. The difference is judgment: how well the model reads a job posting, matches it to your experience, and picks specific language over safe language.&lt;/p&gt;

&lt;p&gt;A stronger model notices you shipped a payments feature under a deadline and writes a bullet about the trade-off you made. A cheaper model writes "improved operational efficiency" and moves on. One reads like a person who was in the room. The other reads like a template.&lt;/p&gt;

&lt;p&gt;The "unlimited" pitch hides this downgrade. You're told you can generate as many resumes as you want, and technically you can. What you're not told is that every one ran through a model chosen for cost, not quality.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why models sound generic in the first place
&lt;/h3&gt;

&lt;p&gt;LLMs predict the next likely token. Without strong, specific input, "likely" collapses to "common," and common resume language is buzzword-heavy by default. The model can't invent your impact. It only knows what you feed it, and when you feed it little, it reaches for legacy filler like &lt;code&gt;synergy&lt;/code&gt;, &lt;code&gt;stakeholder management&lt;/code&gt;, and &lt;code&gt;team player&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;That's also why AI text feels weird even when it's fluent. It's abstract. It describes categories of work ("cross-functional collaboration") instead of the concrete thing you did ("ran weekly syncs between design and backend to unblock the checkout redesign"). Recruiters read that abstraction as evidence you're hiding a thin story, whether or not that's true.&lt;/p&gt;

&lt;h2&gt;
  
  
  The 3 dead giveaways of a generic AI resume
&lt;/h2&gt;

&lt;p&gt;Recruiters spot AI resumes fast because the tells are consistent. Here are the three that matter most, and what each one signals.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Stock phrases with no proof behind them
&lt;/h3&gt;

&lt;p&gt;The clearest giveaway is buzzword-heavy phrasing with nothing to back it up. &lt;code&gt;Results-driven professional with a proven track record&lt;/code&gt; is a claim, not evidence. A human writes &lt;code&gt;cut checkout errors 30% by rebuilding form validation&lt;/code&gt;. One asserts. The other shows.&lt;/p&gt;

&lt;p&gt;The problem isn't that the words exist. It's that people stop at that generic layer and never add the proof. Once a resume leans on stock phrases without a number, a decision, or a specific project, it reads as filler.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Padded or invented metrics
&lt;/h3&gt;

&lt;p&gt;Cheap models love round, vague numbers because they sound impressive and cost nothing to generate. "Increased efficiency by 40%" with no baseline, no timeframe, and no method is a padded metric. Recruiters have read thousands and discount every one.&lt;/p&gt;

&lt;p&gt;Real metrics have texture: what you measured, over what period, and how. "Reduced average API response time from 800ms to 210ms over one quarter by adding caching" is believable because it's specific. If your AI resume is full of clean percentages you can't defend in an interview, that's a tell and a risk.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Identical structure and overly formal tone
&lt;/h3&gt;

&lt;p&gt;AI-written resumes tend to follow the same skeleton: a templated summary, an oversized skills section, then bullets that all start with the same handful of verbs. The language is formal and abstract, with no personal voice and no sense of the decisions you made.&lt;/p&gt;

&lt;p&gt;Modern applicant tracking systems (ATS) like Workday, Greenhouse, and Lever already parse a normal resume without that padding. So the bloated skills section and interchangeable summary aren't helping you pass filters. They just make you look like everyone else who used the same tool.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why one prompt isn't enough for a tailored resume
&lt;/h2&gt;

&lt;p&gt;A single prompt can't tailor a resume properly because tailoring is several different jobs, and one pass does none of them well. When you paste your resume and type "tailor this to the job," the model tries to read the posting, find your matching experience, decide what to emphasize, and rewrite everything, all in one shot. It ends up doing each step shallowly.&lt;/p&gt;

&lt;p&gt;The most common failure is that the model only loosely incorporates the actual job description. You get bullets that are broadly plausible for the role but not tightly aligned to its specific requirements. In a pool where half your competitors used the same tool, loose alignment is what makes resumes blend together.&lt;/p&gt;

&lt;p&gt;If you're going to work with a general chatbot anyway, at least give it a proper brief and split the task into stages: analyze the posting, extract requirements, plan what to emphasize, then rewrite. The prompts that pull specifics out of a model instead of averages are the ones that force each of those steps separately.&lt;/p&gt;

&lt;h2&gt;
  
  
  How a multi-agent pipeline fixes the problem
&lt;/h2&gt;

&lt;p&gt;The fix is to break tailoring into specialized steps and run each one properly, instead of asking one model to do everything at once. That's what a multi-agent pipeline does: separate AI agents handle analysis, keyword matching, strategy, rewriting, and review, and each hands its output to the next.&lt;/p&gt;

&lt;p&gt;This is how Roleframe works, and each step exists to kill a specific source of generic output:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Deep job analysis.&lt;/strong&gt; An agent reads the posting like a senior recruiter: role type, seniority, and every requirement, mapped against your real experience. This tightens alignment to the actual job instead of a generic version of it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Keyword extraction and matching.&lt;/strong&gt; It pulls the exact terms recruiter filters scan for, then checks which your resume already covers and which are real gaps, so nothing gets stuffed in blindly.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tailoring strategy.&lt;/strong&gt; A prioritized plan for this exact role: what to rewrite, reorder, and emphasize, and why. This is the judgment step cheap single-prompt tools skip.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Full rewrite.&lt;/strong&gt; Your summary and bullets get rewritten and the missing keywords woven in honestly, never inventing experience you don't have.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Recruiter-grade final review.&lt;/strong&gt; A second pass audits the result for remaining gaps and anything only you can fix, so you don't ship padded metrics you can't defend.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The point isn't magic. It's that spending real compute on each stage produces specific language, because a model that has actually analyzed the job and your history has something concrete to write about. Roleframe exports the final result as a clean, ATS-friendly PDF that matches the editor exactly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Advanced AI vs. everyday AI: paying only for what matters
&lt;/h2&gt;

&lt;p&gt;The honest way to run good models on every resume is to meter the heavy work instead of promising it's unlimited. That's the trade behind Roleframe's credit-based pricing, and it's the opposite of the "unlimited" model that forces a tool to route everything to the cheapest option.&lt;/p&gt;

&lt;p&gt;Roleframe splits AI into two buckets. Everyday AI is free and unlimited on every plan, including the free one: rewriting a single bullet, checking whether a fix worked, the inline assistant. Advanced AI, the heavy multi-agent work that decides whether you get an interview, costs credits: tailoring a resume to a job, scoring and auditing it, generating a cover letter, and full tailoring reports.&lt;/p&gt;

&lt;p&gt;A paid subscription gives you 1,000 credits a month. At roughly 25 credits to tailor a resume, that's about 40 fully tailored resumes every month, and everyday AI stays free on top. Current advanced-AI costs are roughly 25 credits to tailor a resume, 18 to analyze one, and 15 for a cover letter. Those are current values that can change. You see the cost before you run anything, failed runs are refunded, and there's a 14-day money-back guarantee.&lt;/p&gt;

&lt;p&gt;Why do it this way? Metering the advanced runs means each one can use the best models available. You pay only for the runs that matter, and you never pay for the small stuff. The takeaway for your resume: "unlimited AI" and "high-quality AI" are usually opposites. If quality matters more than volume, that's the trade to look for.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to audit your current resume for AI cliches
&lt;/h2&gt;

&lt;p&gt;Run this on whatever your AI tool gave you before you send it anywhere. It takes about ten minutes and catches the phrasing recruiters flag.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Do the name test.&lt;/strong&gt; Cover your name and read the top third. If the summary could belong to any candidate with your title, rewrite it around one specific thing you're known for.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hunt the stock phrases.&lt;/strong&gt; Delete or replace &lt;code&gt;results-driven&lt;/code&gt;, &lt;code&gt;proven track record&lt;/code&gt;, &lt;code&gt;leveraged&lt;/code&gt;, &lt;code&gt;spearheaded&lt;/code&gt;, &lt;code&gt;synergy&lt;/code&gt;, &lt;code&gt;stakeholder management&lt;/code&gt;, and &lt;code&gt;team player&lt;/code&gt;. Each is a claim begging for proof.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Interrogate every number.&lt;/strong&gt; For each metric, ask: baseline, timeframe, method. If you can't answer all three, the number is padding. Make it specific or cut it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Check verb variety.&lt;/strong&gt; If most bullets open with the same two or three verbs, your resume looks machine-generated. Vary them and lead with the action that actually happened.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Test alignment to the job.&lt;/strong&gt; Put the posting next to your resume. Highlight every requirement your bullets clearly address. Thin coverage means the AI wrote broadly instead of tailoring.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Add the context AI can't invent.&lt;/strong&gt; For your top three bullets, write one clause on why the work mattered or what trade-off you made. That decision logic separates you from the monoculture.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Read it aloud.&lt;/strong&gt; Anything that sounds like a press release gets rewritten in plain words. If you wouldn't say it in an interview, don't put it on the page.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The single highest-leverage move is replacing abstract claims with concrete outcomes. AI defaults to "improved collaboration" because it can't infer what you actually did. Only you know you unblocked the checkout redesign by getting design and backend into one weekly sync. That's the detail that makes a resume sound human, and no model can supply it unless you do.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Why do AI models often sound generic?
&lt;/h3&gt;

&lt;p&gt;Language models predict the most likely next token, and "likely" means "common." Trained on millions of existing resumes and job ads, they default to the average phrasing across all of them. Without specific input from you, they reach for safe, high-level claims like "improved efficiency" instead of the concrete thing you did. Cheap models do this more, because they have less capacity to weigh context and pick specific language.&lt;/p&gt;

&lt;h3&gt;
  
  
  Is it bad if my resume sounds like AI?
&lt;/h3&gt;

&lt;p&gt;Using AI isn't the problem. Many hiring teams now expect polished, keyword-aware resumes and treat them as normal hygiene. The problem is stopping at the generic layer, where your resume becomes interchangeable with everyone else's. When a recruiter can't tell you apart from the next candidate, your resume stops being proof of ability. So edit the AI output until it sounds like you.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why does AI text sound weird even when it's grammatically correct?
&lt;/h3&gt;

&lt;p&gt;Because it's abstract. AI describes categories of work ("cross-functional collaboration") instead of the concrete instance ("ran weekly syncs to unblock the checkout redesign"). The tone is often overly formal, with no personal voice and no sense of the decisions behind the work. Fluent but empty reads as filler.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why does my ChatGPT resume come out so generic?
&lt;/h3&gt;

&lt;p&gt;Usually the brief and the single-pass approach. If you say "make my resume better," the model has nothing specific to work with and falls back on buzzwords. It also tries to analyze the job, match your experience, and rewrite everything in one shot, so it does each step shallowly. Feed it detailed inputs, split the work into stages, and tell it exactly which requirements to align to.&lt;/p&gt;

&lt;h3&gt;
  
  
  Does an "unlimited AI" resume builder produce worse resumes?
&lt;/h3&gt;

&lt;p&gt;Often, yes. To offer unlimited rewrites at a flat fee, a tool has to route most requests to the cheapest model it can afford, and cheap models lean harder on generic phrasing. Metering the heavy work instead means each of those runs can use the best models. If output quality matters more to you than raw volume, look for tools that charge for advanced work rather than promising it's unlimited.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://www.roleframe.ai/blog/why-ai-resume-sounds-generic?utm_source=devto&amp;amp;utm_medium=social&amp;amp;utm_campaign=why-ai-resume-sounds-generic" rel="noopener noreferrer"&gt;roleframe.ai&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>career</category>
      <category>softwareengineering</category>
      <category>llm</category>
    </item>
  </channel>
</rss>
