Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros elementum tristique. Duis cursus, mi quis viverra ornare, eros dolor interdum nulla, ut commodo diam libero vitae erat. Aenean faucibus nibh et justo cursus id rutrum lorem imperdiet. Nunc ut sem vitae risus tristique posuere.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros elementum tristique. Duis cursus, mi quis viverra ornare, eros dolor interdum nulla, ut commodo diam libero vitae erat. Aenean faucibus nibh et justo cursus id rutrum lorem imperdiet. Nunc ut sem vitae risus tristique posuere.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros elementum tristique. Duis cursus, mi quis viverra ornare, eros dolor interdum nulla, ut commodo diam libero vitae erat. Aenean faucibus nibh et justo cursus id rutrum lorem imperdiet. Nunc ut sem vitae risus tristique posuere.
To get developers to fix security vulnerabilities, stop measuring what security sends and start measuring what developers merge. Track your merge rate: the share of security fixes that make it from finding to merged pull request. Then remove the reasons fixes stall at each stage. Send fewer findings and prove each one. Deliver a passing pull request instead of a ticket. Route it to the person who owns the code, cap how many land at once, and escalate before the deadline.
This playbook breaks the path from finding to merged fix into five stages, shows where each one leaks, and gives the fix for each.
Developers aren't refusing to fix security bugs. They're making a reasonable call about where their time goes. A security ticket usually arrives with unclear evidence, no fix, a vague owner and a deadline set by someone else, next to feature work with a product manager waiting on it.
The question is not "how do we make developers care about security." It's "how do we make the security fix the easiest work on their board."
Every security fix passes through the same five stages. Each has its own failure mode.
| Stage | What has to happen | Where it leaks |
|---|---|---|
| 1. Sent | A finding reaches a developer | Too many findings, many of them false or unreachable |
| 2. Accepted | The developer agrees it's real and theirs | Weak evidence, wrong owner |
| 3. Fixed | A change is written | Generic advice, unfamiliar code, the fix breaks the build |
| 4. Reviewed | Someone approves the pull request | No reviewer assigned, the PR is too big to read |
| 5. Merged | The fix ships | Nobody chases it, and it goes stale and conflicts |
Merge rate is stage 5 divided by stage 1. If you only measure findings sent or tickets opened, you're measuring the top of a funnel that may be emptying long before it reaches merge.
What you report shapes what your team optimizes. "Findings sent" rewards volume. "Merge rate" and "time from finding to merge" reward findings that are real, fixes that work and owners who were right.
Report merge rate per team and per finding type. A team with a low merge rate on dependency upgrades but a high one on code fixes is telling you exactly where the friction is.
Every false positive a developer has to dismiss makes the next real finding easier to ignore. In one Nullify study of 14,847 SAST findings across five production tenants, 57% were ultimately classified as false positives. That's more than half the funnel spent on work that should never have reached an engineer.
Filter unreachable code, test fixtures and dead dependencies before a person sees anything. For what's left, attach the evidence: the reachable path, the input that triggers it, and for APIs, a request and response that shows the exploit working.
A ticket asks the developer to understand the vulnerability, find the code, design a fix and test it. A pull request asks them to review a change. Those are very different amounts of work.
A good security fix PR:
Nothing kills a security fix faster than a red build. If the developer has to debug your fix before they can review it, you've handed them a ticket again. Fix CI failures on the PR itself, and only request review once every check is green.
The fastest person to fix a vulnerability is the one who wrote or owns the code. Route using the commit author first, then CODEOWNERS, then the wider team. A finding sent to a team channel is a finding sent to nobody.
Twenty security PRs on one repository on a Monday morning will get closed in bulk or ignored. Cap the number of open security PRs per repository, check each owner's current load before assigning, and release the next fix when the last one merges.
If the same vulnerable dependency or unsafe helper shows up in 40 repositories, run it as one campaign with one fix pattern, one owner and a visible progress count. Developers accept a known, consistent change far faster than 40 slightly different tickets.
Give every fix a deadline by risk tier, and escalate in the channel developers read, usually Slack, with the risk and the date stated. A nudge on day two of a seven-day deadline gets a fix merged. A red dashboard cell on day eight gets an argument.
The cheapest security fix is the one made while the code is still open in the author's editor. Scan every pull request, and comment on the exact line with the fix. A finding caught before merge never enters the backlog at all.
| Metric | What it tells you |
|---|---|
| Merge rate | Share of security fixes that reach merge. The headline number. |
| Time from finding to merge | The developer-facing part of mean time to remediate |
| Time to first review | Whether PRs are reaching a reviewer at all |
| Fix PRs closed without merge | Where your fixes are wrong, unwanted or too big |
| Developer edits to the fix before merge | How often your fix needed rework |
| Findings dismissed as false | How much noise reaches developers |
| SLA compliance by team | Whether deadlines are realistic and met |
Watch the closed-without-merge and dismissed-as-false numbers most closely. They're the clearest signal that the funnel is leaking before developers ever get to fixing.
Nullify is built around the merge, not the alert. Triage filters unreachable code, test fixtures and benign configuration, and scores what's left on reachability, exploitability and business context. Confirmed findings route to the commit author, then CODEOWNERS, then the wider team.
Each fix is a minimal, root-cause pull request that's validated against your build before it opens. Nullify then manages the PR through review, reading CI output and pushing follow-up commits when a check fails. To respect capacity, it keeps at most 3 open fix PRs per repository and 5 per remediation plan. It never auto-merges, so developers approve every change. See how it works on the triage and remediation page.
Usually because the fix is more work than it looks. Security findings often arrive with weak evidence, no proposed change, an unclear owner and a deadline set outside the team, next to feature work with someone waiting on it. Reducing false positives and delivering a tested fix as a pull request removes most of that cost.
There is no published industry benchmark. Track your own merge rate per team and finding type, and aim for it to rise each quarter. A low merge rate on one finding type usually points to a specific problem, such as fixes that break the build or findings routed to the wrong owner.
No. Auto-merging removes the review that catches a fix that's correct for security but wrong for the application. Keep a human approving every merge, and make review fast instead: small, root-cause fixes that already pass CI and explain themselves.
Route each finding to the person who wrote or owns the code, using commit history and CODEOWNERS, rather than to a team queue. Check their current workload before assigning, give each fix an SLA, and escalate directly to them before the deadline.