Safeguard
Supply Chain Security•

Which ecosystems ship security fixes fastest? What the research says

npm releases security fixes fastest and Maven slowest, yet downstream adoption takes months in every ecosystem. Four clocks, eight studies, one SLA model.

Safeguard Security Team
42 min read

On the clock most people mean, npm ships security fixes fastest and Maven slowest: in a study of 2,001 advisories across seven ecosystems, the median npm fix was released the same day it was committed, against 13 days for Maven. But the slowest clock everywhere is downstream adoption, which runs to months, and that is the clock your own team controls.

That one sentence hides a measurement problem. Research papers that report "time to fix" measure at least four different intervals, start them from different dates, and draw on different years and databases. Put their medians in one column and you get a chart that looks precise and means nothing. This post separates the clocks, puts each study's numbers on the clock it actually measured, and ends with an SLA model per ecosystem that a security team can defend to an auditor.

Key takeaways

  • Fix commit to release is fast almost everywhere. Across Composer, Go, Maven, npm, NuGet, pip and RubyGems, the median security release came within 4 days of the fix commit (Imtiaz, Khanom and Williams, data as of March 2021). npm had a median of 0 days; Maven had 13.
  • Most fixes exist before the advisory does. In Maven, 81.6% of CVEs were patched before public disclosure (Yang-Smith and Abdellatif, 2025). In npm, 83.1% of fixed vulnerabilities were fixed before publication, with a median offset of about 19 days early (Robinson et al., 2026).
  • PyPI is the outlier on disclosure order. 40.86% of PyPI vulnerabilities were only fixed after they were made public, and the median time from discovery to a fixed release was about two months (Alfadel, Costa and Shihab).
  • Advisories trail releases by weeks. For 69.1% of advisories published after the fix shipped, the median lag from release to advisory was 25 days, from 2 days for NuGet to 167 days for RubyGems (Imtiaz et al.).
  • Review queues add more time. GitHub reported in June 2026 that advisory processing stretched to "multiple weeks for a meaningful share" of advisories during a record surge, and its own alerting only uses reviewed advisories.
  • Downstream adoption is the longest clock. Direct Maven dependents took a median of 151 days to adopt a fix that already existed. Python projects took a median of 7 months. Transitive Maven exposure grew from a median of 65 days at the direct level to 1,822 days ten levels deep.
  • You do not have to wait for any of the upstream clocks. You can measure and shorten adoption, and for the cases where upstream has no fix yet, you can patch a fork.

The four clocks in a vulnerability's life

Every vulnerability in an open source package passes through a sequence of dates. Not every vulnerability hits every date, and the order is not fixed, which is exactly why studies disagree.

  1. Introduction. The first release that contains the vulnerable code.
  2. Discovery or report. Someone finds the flaw and tells the maintainer, or files it publicly.
  3. Fix commit. The patch lands in the source repository.
  4. Fixed release. A version containing the patch is published to the registry.
  5. Advisory publication. A CVE record or a database advisory goes public.
  6. Tool awareness. Your scanner's data source picks the advisory up, which can be later than publication if the source reviews entries first.
  7. Downstream adoption. Your project, and every project between you and the vulnerable package, moves to a fixed version and ships it.

Grouping those dates gives four clocks that matter for a security programme.

ClockStartsEndsWho controls itTypical study that measures it
A. Fix creationReport or discoveryFix commitUpstream maintainerAlfadel et al. (PyPI, discovery to fixed release)
B. ReleaseFix commitFixed version on the registryUpstream maintainerImtiaz et al. (seven ecosystems)
C. AdvisoryFixed release, or fixAdvisory published and visible to toolsMaintainer, CNA, database curatorsImtiaz et al. (release to advisory); GitHub (review queue)
D. AdoptionFixed version availableYour shipped software uses itYou, and every intermediate maintainerYang-Smith and Abdellatif (Maven direct); Przymus et al. (Maven transitive); Alfadel et al. (Python projects)

There is also a fifth interval that some papers report as their headline: total exposure, from the first vulnerable release to the fix. The 2026 npm study does this. It is a real and useful number, but it starts years before anyone knew the flaw existed, so it cannot be compared with a release clock measured in days.

Which clock do most studies measure?

Most of the academic literature measures clock B, the publication versus fix order, or total exposure, because those are the dates that can be pulled automatically from registries and vulnerability databases. Clock A needs a reliable discovery or report date, which public records rarely contain. The Maven lifecycle paper says so directly: the absence of CVE discovery dates means its mitigation times are "a proxy metric" and a lower bound. Clock D is the least studied and, as the numbers below show, the longest.

When you read a vendor report or a conference talk that says "ecosystem X takes N days to fix", the first question is which of these clocks N measures. The five questions for reading a time to patch report walk through the rest.

The studies and what each one measured

Eight sources carry the numbers in this post. Here is what each one did, in plain terms, before we look at the results.

StudyEcosystemsSampleData as ofClock measuredStatistic
Imtiaz, Khanom, Williams, "Open or Sneaky? Fast or Slow? Light or Heavy?" (arXiv 2112.06804, Dec 2021)Composer, Go, Maven, npm, NuGet, pip, RubyGems4,377 advisories, 2,001 with fix commits for the release analysisAdvisory database snapshot of 5 March 2021B (fix commit to release) and C (release to advisory)Medians
Yang-Smith, Abdellatif, "Tracing Vulnerabilities in Maven" (arXiv 2502.04621, Feb 2025)Maven3,362 CVEs, 1,470 artifacts, 190,945 releasesMSR 2025 challenge dataset with OSV dataPublication versus patch order; D for direct dependentsMeans by severity; medians for adoption
Przymus et al., "Out of Sight, Still at Risk" (arXiv 2504.04803, Apr 2025)Maven2,676 CVEs, 132,235 projects, 3.38 million artifactsAugust 2005 to August 2024D, cumulative through transitive levelsKaplan Meier, mean and quartiles
Robinson et al., "Original Sin of npm" (arXiv 2604.17668, Apr 2026, accepted to ACM ASIA CCS 2026)npm1,077,946 sampled packages, about 1,500 unique vulnerabilitiesnpm snapshot of 5 September 2023; publications 2015 to 2023Total exposure (introduction to fix); publication versus fix offsetKaplan Meier medians
Alfadel, Costa, Shihab, "Empirical Analysis of Security Vulnerabilities in Python Packages"PyPI1,396 reports, 698 packages, 2,224 GitHub projectsReports published 2006 to June 2021A (discovery to fixed release); disclosure order; D for projectsKaplan Meier medians
Zerouali, Mens, Decan, De Roover, npm and RubyGems dependency networks (arXiv 2106.06747, v2 Mar 2022)npm, RubyGemsCommercial advisory database2021Disclosure time trends; fixability within same major versionMedians, shares
Sridharkumar et al., "Detecting Protracted Vulnerabilities" (arXiv 2603.27067, Mar 2026)NVD CVEs with GitHub artifacts20,951 CVEs1999 to July 2024Long gaps between fix and disclosureMedians on a sample
GitHub blog, "Inside the Advisory Database" (29 June 2026)All GitHub reviewed ecosystemsOperational figuresJanuary to May 2026C (review queue)Counts, processing time

Two of these datasets came from a commercial vulnerability database run by a security vendor. We name the papers, not the vendor, and note where that origin matters.

Clock B: how quickly a fix commit becomes a release

This is the clock that answers the headline question most directly, and it has the cleanest cross ecosystem study.

Method

Imtiaz, Khanom and Williams started from 4,377 advisories covering 4,812 security releases in 2,217 packages across seven ecosystems. For the release timing question they kept the 2,001 advisories where they could identify the fix commit, then measured the days between that commit and the first release that contained it. They checked a sample of the data by hand and report about 96% accuracy for this subset. Release dates came from each registry's API, except for Maven (crawled from Maven Central) and Go (repository tags, since Go has no central upload registry).

Results by ecosystem

Here is the ranked table this post is named for. It ranks ecosystems by median days from fix commit to release.

RankEcosystemAdvisories with fix commitMedian days, fix to releaseAdvisory published before the fix was committedAdvisory published before the fix was released
1npm553013.0%20.4%
2Composer (PHP)18317.1%14.8%
3 (tie)NuGet (.NET)70311.4%20.0%
3 (tie)RubyGems11338.0%13.3%
5 (tie)Go184611.4%26.1%
5 (tie)pip (PyPI)324612.0%24.4%
7Maven (Java)574137.0%26.7%
All seven2,001410.1%22.4%

Source: Imtiaz, Khanom and Williams, arXiv 2112.06804, Table 3. Data reflects the advisory database as of 5 March 2021.

The paper adds detail behind the medians. In npm, 50.3% of security releases came within 24 hours of the fix. In Maven, only 14.9% did, and Maven also showed the widest spread. Across all ecosystems the first quartile was 0 days and the third quartile was 20 days, so a quarter of releases still came at least 20 days after the fix. High severity advisories were released faster than medium ones (median 3 days against 5).

Why npm is fast and Maven is slow on this clock

The paper does not test causes, so treat these as reasonable readings rather than findings. Publishing to npm is a single command by a single maintainer, and many npm packages are small with one maintained branch. Maven artifacts are often parts of larger multi module projects with release trains, staging repositories and signing steps. The paper's manual review of 44 slow releases found that the most common pattern (27 cases) was maintainers waiting until the release to publish the advisory, which removes the pressure to release quickly. It also found 5 cases where the fix shipped fast on the latest branch but was slow to reach an older maintained branch. If you run an older major version, your clock B can be much longer than the ecosystem median.

What this clock tells you, and what it does not

Clock B is short. For most ecosystems it is measured in days, not weeks. That means that once a fix is committed upstream, waiting for "the release" is rarely what keeps you exposed for months. The paper also makes a sharper point: during those days the fix is public in the repository while the advisory is not, so an attentive attacker can read the commit before your scanner knows anything is wrong.

Clock C: from release to a published advisory, and then to your tools

Release to advisory publication

The same paper measured how long advisories took to appear after the fixed release. Of 3,655 advisories with both dates, 2,527 (69.1%) were published after the security release. For those, the median gap was 25 days.

EcosystemAdvisories published after the fixed releaseMedian days from release to advisory
NuGet150 of 241 (62.2%)2
Go145 of 211 (68.7%)15
pip367 of 569 (64.5%)19
Composer509 of 751 (67.8%)21
npm540 of 735 (73.5%)24
Maven693 of 937 (74.0%)43
RubyGems123 of 211 (58.3%)167
All2,527 of 3,655 (69.1%)25

Source: Imtiaz et al., arXiv 2112.06804, Table 8. Advisory date is the earlier of NVD and one commercial advisory database.

The RubyGems number is driven by advisories that never received a CVE. The authors found that RubyGems advisories without a CVE had a median delay of 948 days, against 42 days for those with a CVE. Their explanation is that some security fixes were found years later by people scanning repositories for unannounced fixes. Across all ecosystems, CVE advisories had a median delay of 21 days and non CVE advisories 55 days. High severity advisories appeared faster than medium ones (20 days against 33).

So the ranking flips. npm, first on clock B, sits in the middle on clock C. Maven is slow on both. RubyGems, joint third on clock B, is far behind on clock C. Any single "fastest ecosystem" claim has to say which clock it ranks.

How much a review backlog adds to the "known" date

An advisory being published somewhere is not the same as your tooling acting on it. GitHub's Advisory Database is a good public example because GitHub documents how it works.

According to GitHub's documentation, advisories come in three kinds. Reviewed advisories are checked for validity before publication. Unreviewed advisories are published automatically from the NVD feed. Malware advisories cover malicious packages. GitHub's own alerting does not raise alerts for unreviewed advisories, because that type of advisory "isn't checked for validity or completion". Reviewed advisories cover Composer, Erlang, Go, GitHub Actions, Maven, npm, NuGet, pip, Pub, RubyGems, Rust and Swift.

In a post dated 29 June 2026, GitHub described what happened when inbound volume broke records:

  • May 2026 saw 1,560 reviewed advisories, the most in the database's history and more than five times the typical month.
  • From March to May GitHub made more than 6,000 advisory decisions a month.
  • Private vulnerability reports rose from about 550 a week in January to more than 3,000 a week for most of May. Repository advisories rose from about 650 a week to more than 5,000.
  • Starting in mid April, processing times stretched first to about a week and then to "multiple weeks for a meaningful share" of advisories.
  • Critical issues were prioritised for review.

The post does not give a backlog size or a per ecosystem breakdown, so we cannot put a precise number on it. What it does show is that clock C has a second stage that grows when volume spikes, and that the stage is invisible if you only look at the advisory's "published" timestamp. The OSV schema, for example, defines published only as "the time the entry should be considered to have been published", which is the database entry's date, not the date the flaw became known.

For a team, the practical consequence is simple. If your scanner relies on a reviewed feed, its "known" date can trail the CVE record by days to weeks in a busy month. That is one more reason not to start your SLA clock only when a ticket appears.

Clock A and the disclosure order: fixed before or after the world knows?

Maven: most fixes predate disclosure

Yang-Smith and Abdellatif enriched the MSR 2025 Maven dependency graph with OSV data for 3,362 CVEs. They classified each by the order of two dates: the CVE publication date and the date of the first patched release.

  • 81.6% of CVEs were patched before public disclosure.
  • The paper's results section says 12.8% had no patch in the dataset and 5.6% were published before the patch. Its introduction states the reverse (12.8% disclosed before a patch, 5.6% unresolved). We could not resolve this from the paper, so read those two numbers as "together about 18%".
  • For CVEs published before a patch, the mean time to a patched release fell with severity: 151 days for low, 123 for moderate, 84 for high and 78 for critical. The abstract presents this as a 48.3% faster response for critical issues.

Note that those severity figures are means from the paper's Table II, not medians. The abstract describes the trend as "response time", which is easy to confuse with the 151 day median in the adoption analysis below. They are different measurements that happen to share a number.

The authors list their own limits. CVE records often lack a lower bound for affected versions, and there are no discovery dates, so mitigation time is a lower bound on how long maintainers actually knew.

npm: fixes typically land about 19 days before publication

Robinson and colleagues sampled 1,077,946 npm packages from a September 2023 snapshot, built dependency networks with the deps.dev API, and matched vulnerabilities through OSV and NVD. For each vulnerability they compared the fix release date with the publication date.

  • 83.1% of vulnerabilities were fixed before publication, 9.7% after publication, and 7.1% remained unfixed. (The paper's findings paragraph gives slightly different figures, 83.4% and 6.9%.)
  • The Kaplan Meier median of the publication to fix offset was minus 0.62 months, about minus 19 days. A negative offset means the fix shipped first. Half of the fixed vulnerabilities had a fix at least about 19 days before the advisory appeared.

The authors read this as maintainers publishing advisories once a fix exists, which fits coordinated disclosure, but they note they did not verify it.

What the 59 month npm figure actually measures

The same paper reports that it takes about 59 months for 50% of npm vulnerabilities to be fixed. This number has been quoted as if npm maintainers take five years to respond. They do not, and the paper does not say so. Here is what it measures:

  • Start: the date the first vulnerable version was uploaded to npm, not the report or advisory date.
  • End: the date a fixed version became available.
  • Statistic: a Kaplan Meier median with unfixed vulnerabilities treated as censored, not an average.
  • Companion figure: the median from introduction to publication was 71 months.

Read together, the two numbers say that npm vulnerabilities typically sat undiscovered in released code for years, and that the fix usually arrived shortly before the advisory. That is a statement about how long bugs hide, not about how slowly maintainers fix them. If you use the 59 month figure in a slide, label it "first vulnerable release to fix".

PyPI: four in ten fixed only after disclosure

Alfadel, Costa and Shihab studied 1,396 vulnerability reports affecting 698 PyPI packages, drawn from a commercial advisory database, covering reports published up to June 2021. Their journal version extends a 2021 conference paper.

  • Vulnerabilities took a median of 39 months to be discovered after the vulnerable code was introduced, against 26 months for npm in the comparison study they cite.
  • 40.86% of vulnerabilities received their first fixed release only after public disclosure. 37.77% were fixed between discovery and publication, and 18.82% were fixed before the discovery date was recorded.
  • For vulnerabilities fixed after discovery, the median time from discovery to fixed release was about 2 months. 7.37% took more than a year. Severity made no statistically significant difference.
  • The npm comparison they cite found a median of 11 days from discovery to fix and 82% fixed before publication.

The 40.86% figure is the key contrast. In npm and Maven the large majority of fixes predate disclosure. In PyPI, in this sample, a large minority did not, which means a meaningful share of PyPI advisories arrived with no fixed version to move to. The authors attribute the difference to community practices and reporting policies rather than to anything inherent in Python.

Protracted vulnerabilities: the long tail of all clocks

Sridharkumar and colleagues looked at the opposite end. From 20,951 NVD CVEs with GitHub artifacts (1999 to July 2024), they classified 3,228 (15.4%) as protracted, meaning they had a long gap, more than a year in their selection, between report and patch or between patch and public disclosure. In a sample of 94 such CVEs, the median gap from fix to patched release was 9 days, but the median from patch to public disclosure was 619 days. The most common cause in that sample was delayed reporting to NVD (65 of 94). Their detector evaluation covers C, C++ and Java only, and the paper's counts are not fully consistent across sections.

The lesson is that a vulnerability can be fixed upstream and silently sit in your dependency tree for well over a year before any advisory tells your scanner to look. Keeping dependencies reasonably current is the only defence against fixes nobody announced.

Clock D: downstream adoption, the longest clock

Every study that measured adoption found it to be longer than every upstream clock. This is also the clock that a security team can actually change.

Maven direct dependents

Yang-Smith and Abdellatif classified how direct dependents adopted fixes, by the order of three events: patch release, CVE publication and dependent adoption.

Adoption patternOrder of eventsCasesShareMedian days
Available patch adoptionPatch, then CVE, then dependent adopts46,53662.9%151
Reactive adoptionCVE, then patch, then dependent adopts3,3134.5%249
Proactive adoptionPatch, then dependent adopts, then CVE24,14432.6%Not reported (wide spread)

Source: Yang-Smith and Abdellatif, arXiv 2502.04621, section III C. Response time is measured from the earliest patch date to the latest affected date in the dependent.

An earlier summary of this paper described 151 days as the maintainer response "where a fix was already available" and 249 days "where no patch existed at disclosure". The second half is close: reactive adoption covers CVEs disclosed before a patch existed. The first half needs a correction. 151 days is how long direct dependents took to stop shipping the vulnerable version when the fix was already out before the CVE was published. It is downstream adoption, not upstream response. In other words, most of the delay sat with consumers who had a fix available.

Maven transitive dependents

Przymus and colleagues extended the same Maven graph to transitive dependencies across 132,235 projects and 2,676 CVEs (August 2005 to August 2024) and ran a Kaplan Meier survival analysis by dependency depth.

Dependency levelMedian cumulative days to fixMean cumulative daysMedian days for that single levelDependencies at that level
0 (the vulnerable artifact)65215623,046
114042940184,579
233459740417,797
335579241439,878
45841,10444455,303
56761,14539482,524
68881,36441428,033
81,6171,90037248,152
101,8222,07541149,685

Source: Przymus et al., arXiv 2504.04803, Table II (levels 7 and 9 omitted for space).

Two things stand out. First, each individual hop is quick and stable: about 40 days at the median from a vulnerable version to the next clean release, at every level. Second, those hops add up. A vulnerability five levels down took a median of 676 days, nearly two years, to clear, and the busiest levels are exactly the middle ones. The authors fit a rough rule of thumb for the mean: about six months per level plus eight months. They are careful to call that model hypothesised rather than validated.

The paper has one wording inconsistency worth knowing: it describes the cumulative clock as starting at CVE introduction, while its figure axis and its limitations section refer to CVE publication. It also tracks only the most recent affected version of each artifact and ignores embargo periods, both of which make the figures a lower bound.

Python projects

Alfadel and colleagues followed 2,224 GitHub Python projects. 55.62% depended on at least one vulnerable package at some point. The median time for a project to move from a vulnerable dependency version to a fixed one was 7 months, three and a half times the upstream median of 2 months. Part of this is release cadence: the median project needed 2 releases to make the update, and the median gap between releases was 3 months.

npm and RubyGems

The 2026 npm paper does not measure adoption itself; it quotes external estimates instead. The Zerouali study of npm and RubyGems found that 33% of the vulnerable dependencies projects were exposed to, and 40% of those packages were exposed to, already had a fix within the same major version range. That means a large share of exposure needed no breaking upgrade at all, only an update that nobody had made.

Putting the clocks side by side

This table puts every headline figure on its own clock. Read across a row only. Do not compare numbers in different rows.

ClocknpmMavenPyPIRubyGemsSource and data date
Introduction to discovery, median26 monthsNot measured39 monthsNot measuredAlfadel et al. (PyPI to June 2021), citing Zerouali et al. for npm
Discovery to fixed release, median11 daysNot measuredAbout 2 monthsNot measuredAlfadel et al., same
Fixed before publication83.1%81.6%18.82% before discovery plus 37.77% before publicationNot measuredRobinson et al. (2023 snapshot); Yang-Smith and Abdellatif (2025); Alfadel et al.
Fix commit to release, median0 days13 days6 days3 daysImtiaz et al. (March 2021)
Release to advisory, median (if advisory came after)24 days43 days19 days167 daysImtiaz et al. (March 2021)
First vulnerable release to fix, KM median59 monthsNot measuredNot measuredNot measuredRobinson et al. (2023 snapshot)
Downstream adoption, medianNot measured directly151 days (direct, fix already out); 65 to 1,822 days cumulative by depth7 months (GitHub projects)Not measuredYang-Smith and Abdellatif; Przymus et al.; Alfadel et al.

The pattern is consistent even though the samples are not. Upstream clocks are measured in days to weeks once a vulnerability is known. Adoption clocks are measured in months to years.

Why survivorship and censoring bias move the medians

Time to fix studies are survival problems: you watch a population until an event happens, and some members never reach the event before the study ends. How a study handles that changes the median, sometimes a lot. Our post on survivorship bias in time to patch statistics covers the general case; here is how it plays out in these papers.

Dropping unfixed items makes medians look faster. If a study only measures vulnerabilities that have a fix, the slow tail that never got fixed vanishes from the sample. The 2026 npm paper avoids this by treating the 7.1% of unfixed vulnerabilities as censored in a Kaplan Meier estimate. The Maven adoption analysis excludes "No Patch" cases entirely, so its 151 and 249 day medians describe only vulnerabilities that were eventually patched.

Snapshot timing truncates long tails. A study that ends in March 2021 cannot observe a fix that arrives in 2023. Kaplan Meier handles this correctly only if the censoring is unrelated to how slow the item is, which is rarely true for abandoned packages.

Removing dead packages biases toward active ones. The npm study dropped about 400,000 sampled entries that were unavailable or deprecated. That makes the remaining sample more actively maintained than npm as a whole, which probably shortens its fix times.

Lower bounds everywhere. The Maven transitive study tracks only the most recent affected version and ignores embargoes. The Maven lifecycle study has no discovery dates. Both say their numbers are lower bounds. The real clocks are longer.

Database dates are not event dates. The npm study found that OSV and NVD publication dates for the same vulnerability differed by about 5 days on average, with outliers over five years. Imtiaz and colleagues took the earlier of two databases. A study that used only one would get a different clock C.

Old data, changing ecosystems. The release and advisory study reflects March 2021. Since then registries have added provenance, private vulnerability reporting has grown (GitHub reports more than 1.7 million repositories have it enabled), and CVE volume has climbed. The direction of the findings is likely still right; the exact medians should be treated as historical.

How we measured

We did not run new measurements for this post. We read each paper's methods and results sections in full where we could fetch them, took the figures from the paper's own tables rather than from summaries, and recorded for each figure:

  1. The clock. Which two dates bound the interval.
  2. The statistic. Median, mean, Kaplan Meier median, or share.
  3. The sample. Ecosystems, counts and data date.
  4. The source of dates. Registry APIs, OSV, NVD, a commercial database, or repository tags.

Every table above carries its clock and source. We never mixed clocks in one column. Where a paper reported different numbers for the same thing in two places, we report both and say so. Where a figure came from a paper citing another paper (the npm 11 day and 26 month figures, cited by the PyPI study), we say so. Two of the datasets came from a commercial vulnerability database; we name the papers and describe the database generically.

We also checked one earlier internal summary against the source. It described the Maven 151 and 249 day figures as maintainer response times. The paper defines them as direct dependent adoption times, and we use that definition here.

If you want the same discipline in your own reporting, the post on two clocks for OS and dependency time to fix shows how to separate them in a dashboard, and why time to fix beats vulnerability count explains why the metric is worth the effort. The data notes on median time to fix by ecosystem and median time to fix vulnerabilities by ecosystem cover advisory database figures we do not repeat here.

Measure your own four clocks: a walkthrough

Published medians tell you what is normal. Your own clocks tell you where your time goes. Here is how to measure each one for a single vulnerability, using public APIs and the tools each ecosystem ships.

Step 1: get the advisory's published date and fixed version

The OSV API returns the database entry with published, modified and the fixed event for each affected range.

# Replace with the advisory ID you care about
curl -s https://api.osv.dev/v1/vulns/GHSA-xxxx-xxxx-xxxx \
  | jq '{id, published, modified, fixed: [.affected[].ranges[].events[] | select(.fixed) | .fixed]}'

Remember that published is the entry's date in that database, not necessarily the CVE date. Record both if you have them.

Step 2: get the fixed release date from the registry

# npm: every version's publish time
npm view lodash time --json | jq '."4.17.21"'

# PyPI: upload time of a version
curl -s https://pypi.org/pypi/requests/2.32.0/json | jq -r '.urls[0].upload_time_iso_8601'

# Go: module version time from the module proxy
curl -s https://proxy.golang.org/golang.org/x/net/@v/v0.23.0.info | jq -r .Time

# RubyGems: version created_at
curl -s https://rubygems.org/api/v1/versions/rack.json | jq -r '.[] | select(.number=="3.0.9.1") | .created_at'

For Maven, check the release date on Maven Central for the artifact version. Imtiaz and colleagues found one case where Maven Central's listed date was later than the repository tag, so cross check against the project's git tag if the number matters.

Step 3: find the fix commit date

git clone --filter=blob:none https://github.com/OWNER/REPO.git && cd REPO
git log -1 --format='%H %cI %s' FIX_COMMIT_SHA

Fix commit to registry release is your clock B for that vulnerability.

Step 4: find when your project adopted the fix

# npm: first commit where the lockfile resolved the fixed version
git log --reverse --format='%h %cs' -S'"version": "4.17.21"' -- package-lock.json | head -1

# Python with a requirements file
git log --reverse --format='%h %cs' -S'requests==2.32.0' -- requirements.txt | head -1

# Maven: confirm the resolved version today, including transitive paths
mvn -q dependency:tree -Dincludes=org.apache.commons:commons-text

# Go: which module versions are in the build
go list -m all | grep golang.org/x/net

Adoption is the gap between the fixed release date and that commit, and then the gap to the deploy that shipped it. That second part is the one most teams never measure.

Step 5: see what is still exposed right now

npm audit --omit=dev
pip-audit -r requirements.txt
govulncheck ./...
mvn versions:display-dependency-updates

Or run one scan across all of them and keep the JSON:

safeguard scan --dir .
# results are written as JSON under ./output

Do this for your last ten high or critical findings and you will have your own clock D median, which is a far better basis for an SLA than any study.

What SLA should you set per ecosystem?

The research supports a few defensible principles. It does not support a single universal number, and you should be wary of anyone who quotes one as "the industry standard".

Start the clock at fix availability, not at ticket creation

Because most fixes in npm and Maven exist before the advisory, and because review queues can add weeks, an SLA that starts when your scanner raises a ticket hides real exposure. Start it at the later of two dates: the fixed release date, or the advisory publication date. Record the scanner alert date separately so you can see feed lag.

Use ecosystem only where it changes the clock you control

Upstream ecosystem differences mostly affect clocks A to C. Your SLA governs clock D. The ecosystem matters to clock D in two ways: how hard upgrades are (Maven's deep transitive graphs and BOM pinned versions make upgrades slower), and how often a fix does not exist yet (PyPI's 40.86% fixed after disclosure means more cases with no version to move to).

A model to adapt

SituationSuggested target from fix availabilityWhy
Known exploited, any ecosystem, direct dependencyDays, not weeksExploitation removes the time you thought you had
Critical or high, fix in the same major version14 to 30 daysZerouali et al. found a third or more of exposure had a same major fix; these updates are usually low risk
Critical or high, fix needs a major upgrade30 to 60 days with a tracked exceptionBreaking changes need testing; track the exception rather than miss silently
Transitive only, deep in a Maven graphSame target, but measured on an override or managed versionWaiting for each intermediate maintainer adds about 40 days per level at the median
No upstream fix exists (common in PyPI, about 18% of Maven CVEs)Compensating control within days; patched fork or replacement on a dated planThere is nothing to upgrade to, so the SLA has to name a different action
Medium and lowNext routine dependency update cycleKeeping current also catches fixes nobody announced

As a historical reference point, CISA's BOD 19-02 required US federal agencies to remediate critical findings on internet facing systems within 15 calendar days and high within 30, counted from initial detection. CISA's page now marks that directive as revoked and superseded by BOD 26-04, so cite it as precedent, not as current federal policy. These are suggestions to adapt to your risk appetite, not requirements.

Report the clock you measured

When you report against the SLA, report the clock: "median days from fixed release to production deploy, high and critical, direct and transitive". That one phrase prevents most arguments with auditors and leadership about whether 30 days is good or bad.

Common mistakes

  • Comparing medians from different clocks. A 59 month npm exposure figure and a 4 day release figure are not fast and slow versions of the same thing.
  • Treating "fixed before publication" as "safe". In the release study, fixes sat public in repositories for days to weeks before advisories, and 22.4% of advisories came out before the fix was released. Attackers can read commits.
  • Starting the SLA at the scanner alert. Feed review queues and advisory lags mean the alert can arrive weeks after the fix. Start at fix availability.
  • Ignoring transitive depth. A direct dependency SLA says nothing about a vulnerability five levels down, which took a median of 676 days to clear in Maven.
  • Assuming no CVE means no fix. RubyGems advisories without a CVE took a median of 948 days to be published after the fix shipped. Routine updates pick up fixes nobody announced.
  • Quoting old medians as current. The cross ecosystem release study reflects March 2021. Label the data date every time.
  • Waiting for upstream when no fix exists. About four in ten PyPI vulnerabilities in one study had no fix at disclosure. Waiting is a choice, not the only option.
  • Mixing means and medians. The Maven severity figures are means; the adoption figures are medians. Long tails make means much larger.

Fix it without waiting for upstream

The research is clear that the slowest clock in this post is downstream adoption, and that is the clock you own. The second worst case is the one where clock A never finishes, because upstream has not shipped a fix.

Whatever the vulnerability, most of the risk sits in two gaps. The first is the time between a fix being published and that fix actually running in your production builds. The second, and worse, is the time before any fix exists at all, while a maintainer works out a patch and a release schedule. Waiting through both gaps is a habit, not a requirement. Safeguard gives teams three ways to close them.

1. Autonomous remediation: pull requests, not tickets

When a fixed version exists, Safeguard's Griffin models open a tested, policy gated pull request that moves the affected dependency to the safe version. You can run it on one repository or in bulk across every project that carries the vulnerable version. Remediation covers eight categories, including dependencies, licenses, security posture and findings. Reachability analysis ranks the vulnerable code paths your application actually calls first, so the first pull requests you merge are the ones that matter most. Autonomous remediation ships switched off, with every category set to Manual, so your team decides how much runs on its own and what still needs a human approval.

2. Gold Open Source: the safe version in seconds, free

gold.safeguard.sh is free and needs no login. Search any CVE or package to see affected and fixed versions, CVSS, EPSS, CISA KEV status and a recommended safe version, or use the "Am I affected?" checker. The same data is available through a free read API, README status badges and RSS threat feeds. The safeguard-sh/gold-scan-action GitHub Action can fail a build on a known exploited vulnerability, on any known vulnerability, or never, so a version you have just removed cannot quietly come back in next week's merge.

3. Gold Registry: start from components that are already fixed

registry.safeguard.sh provides hardened, drop in replacements for upstream packages and container images. Every Gold artifact is held continuously to zero exploitable critical or high CVEs, zero malware and a completed license check, with SLSA L3 or higher provenance, a Sigstore signature and a public evidence page you can hand to an auditor. An artifact loses its Gold badge if it regresses. Teams can point their own package directory at the registry so hardened equivalents resolve without changing how developers install anything.

When upstream has no fix yet, or will not ship one, Safeguard first works to get the fix accepted upstream. If the issue is severe or upstream will not move, Safeguard builds a fork, fixes the vulnerability there and publishes a hardened Gold build, so you are not stuck on a maintainer's release schedule. You can also request a hardened, compatibility tested build of a specific package. This fork and patch flow is in early access today, so ask which packages it covers before you plan around it.

Your situationWhat to use
A fixed version existsAutonomous remediation opens the upgrade pull request; Gold Open Source confirms the safe version
You need to know today whether you are affectedGold Open Source lookup and "Am I affected?" checker, free and without login
You want vulnerable versions to stop shippingThe Gold scan GitHub Action in CI, plus Safeguard policies and gates
Upstream has no fix yet, or will not ship oneA custom Gold request; fork and patch (early access)
You want to start clean on new projectsPull hardened components and images from Gold Registry

One honest limit: when the vulnerable code lives in a vendor appliance, a hosted service or an operating system runtime you do not build yourself, the fix still has to come from that vendor or distribution. The steps above apply to the open source dependencies and container images you build and ship, which is where most teams carry the largest and least tracked share of their exposure.

FAQ

Which programming ecosystem releases security fixes the fastest?

On the fix commit to release clock, npm, with a median of 0 days and half of releases within 24 hours, in a study of advisories as of March 2021. Composer was next at 1 day. Maven was slowest at 13 days. On other clocks the order changes.

Which ecosystem is slowest to patch vulnerabilities?

Maven was slowest on both release (13 days) and advisory publication (43 days) in the same study. RubyGems was slowest on advisory publication overall at 167 days, driven by advisories without CVEs. On downstream adoption, every ecosystem studied takes months.

How long does it take open source maintainers to fix a vulnerability?

Once a vulnerability is reported, studies find a median of about 11 days for npm and about 2 months for PyPI from discovery to a fixed release. Once the fix is committed, the median release follows within about 4 days across seven ecosystems. Data dates are 2021 and earlier.

What does it mean when a vulnerability is fixed before it is published?

It means a fixed version was on the registry before the CVE or advisory went public, usually through coordinated disclosure. It happened for 83.1% of npm and 81.6% of Maven vulnerabilities in recent studies. It also means the fix was visible in public code before your scanner knew about it.

Is it true that npm vulnerabilities take five years to fix?

No. The 59 month figure from a 2026 npm study measures from the first vulnerable release, often years before anyone knew of the flaw, to the fix. Once known, npm fixes usually arrive before or shortly after publication.

How long do projects take to update vulnerable dependencies?

Longer than upstream takes to fix them. Direct Maven dependents took a median of 151 days to adopt a fix that already existed. Python projects took a median of 7 months. Transitive Maven exposure five levels deep took a median of 676 days to clear.

Why do GitHub advisories sometimes appear weeks after a CVE?

GitHub reviews advisories before its alerting uses them. In a June 2026 post GitHub said record volume stretched processing to multiple weeks for a meaningful share of advisories from mid April. Unreviewed advisories are visible but do not trigger GitHub's alerts.

What is a good SLA for fixing vulnerable dependencies?

There is no single standard. Start the clock at fix availability, use days for known exploited issues, roughly 14 to 30 days for critical and high fixes within the same major version, and a dated plan with compensating controls where no upstream fix exists.

Should my SLA differ by programming language?

Only where the ecosystem changes the work. Deep Maven graphs make transitive fixes slower, and PyPI more often has no fix at disclosure. The SLA itself should apply to adoption, which you control, rather than to upstream speed.

What can I do when upstream has not released a fix?

Apply a compensating control, check whether a fixed fork or hardened build exists, and plan a replacement if the package is unmaintained. Safeguard's fork and patch flow covers this case and is in early access.

See how Safeguard would help

Measuring adoption is only half the job; shortening it is the other half. These demos show the parts of Safeguard that act on clock D.

The first demo is a real Safeguard CLI session. You install it, open the interactive terminal and ask it to fix the lodash CVE in a repository. It reads the finding and the advisory, asks before each command, edits package.json to lodash 4.17.21, runs npm install and npm test with your approval, prints a summary and pushes nothing. That is the adoption clock collapsed to minutes for a direct dependency where a fix already exists, the most common case in every study above.

Click through it at your own pace, or open it full screen.

The second demo sets up the Safeguard runner on your own machine, approves it with its device code and then scans from the terminal. Running scans close to the code is how you measure your own adoption clock on every repository, rather than relying on a feed that may trail the fix by weeks.

Click through it at your own pace, or open it full screen.

The third demo connects Claude to the Safeguard MCP server with OAuth and lets you choose which tools Claude can use. For a metrics owner, that means asking for findings, fixed versions and project lists in plain language while you build the per ecosystem SLA report described above.

Click through it at your own pace, or open it full screen.

To try it on your own repositories, download Safeguard and follow the CLI documentation.

Quick check

A report says Maven takes 151 days to fix vulnerabilities. Which clock is that?

In the 2025 Maven lifecycle study, 151 days is the median time for direct dependents to adopt a fix that was already released before the CVE was published. It is downstream adoption, not maintainer response. The paper also reports a 151 day mean for low severity CVEs published before a patch, a separate measurement.

Why should an SLA start at fix availability rather than at the scanner alert?

Because most npm and Maven fixes exist before the advisory, advisories trail releases by a median of 25 days in one study, and review queues can add weeks. Starting at the alert hides that exposure.

Sources

Last reviewed: 23 October 2026. Study figures are as published; check the linked papers for later revisions.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.