Safeguard
Open Source Security

Measuring Project Health: Bus Factor, Commit Velocity, an...

Bus factor, commit velocity, and maintainer concentration predicted the xz-utils and event-stream incidents before any CVE did. Here's how to read these proxies — and where they mislead.

Vikram Iyer
Security Researcher
9 min read

Every software supply chain risk conversation eventually lands on a CVE database. But the vulnerabilities that make headlines — Log4Shell in December 2021, the xz-utils backdoor in March 2024 — often trace back to a quieter, earlier signal: a project running on fumes. Log4j had a maintenance team stretched across volunteers with day jobs. xz-utils was effectively a one-person operation before a patient attacker spent two years engineering their way into commit access. Neither project's CVE count predicted the crisis. Their maintenance patterns did.

This is the case for project health metrics: bus factor, commit velocity, issue response latency, and maintainer concentration. None of these numbers proves a package is insecure. But together they measure something a CVE feed cannot — the likelihood that when a vulnerability is found, someone is actually there to fix it, and the likelihood that an attacker could quietly take over in the meantime. Here's how to read them, and where they mislead.

What Is Bus Factor, and Why Does a Number as Low as 1 Matter?

Bus factor is the minimum number of people who would need to disappear before a project stalls, and a bus factor of 1 means a single person is the entire safety net. The term is dark on purpose — "get hit by a bus" — but the real-world triggers are more mundane: burnout, a new job, a custody battle, a health scare. xz-utils is the canonical case. By 2022, the compression library — a dependency of OpenSSH on most Linux distributions — had one active maintainer, Lasse Collin, who had publicly discussed his declining bandwidth on the project's mailing list as far back as 2019. An account calling itself "Jia Tan" began contributing patches in 2021, built trust over roughly two years, and was eventually handed co-maintainer and release access. In February 2024, that access was used to insert a backdoor into the build scripts, discovered only by chance when a Microsoft engineer, Andres Freund, noticed SSH logins were 500 milliseconds slower than expected. A bus factor of 1 didn't cause the backdoor, but it created the opening: there was no second maintainer to question a new contributor's sudden authority over release tarballs.

Bus factor of 1 is far from rare. Research groups analyzing npm and PyPI have repeatedly found that a large share of widely-depended-upon packages — commonly cited in the 15-25% range depending on the ecosystem and sampling method — have exactly one person with commit or publish rights. The 2016 left-pad incident (a package with 11 lines of code, unpublished by its sole maintainer over a naming dispute, breaking builds across the npm ecosystem) and the 2022 colors.js/faker.js sabotage (its sole maintainer intentionally pushed infinite-loop code into production versions) are both bus-factor-1 failures, just without an external attacker.

How Does Commit Velocity Signal Risk, and Why Did a Slowdown Get Missed at xz-utils?

Commit velocity signals risk when it drops sharply on a widely-used project, because a stall in normal maintenance is often the first visible symptom of the human problems that precede an incident. On xz-utils, Collin's commit frequency measurably declined starting around 2020, exactly the window in which "Jia Tan" began appearing in mailing list threads offering to help. Nobody was tracking that velocity drop as a security signal at the time — it read as an ordinary open source lull, the kind that happens to thousands of projects every year.

The trouble with commit velocity as a standalone metric is that it's noisy in both directions. A drop can mean abandonment, or it can mean a stable, "done" library that legitimately needs few changes — sqlite's core is glacially slow to change and that's a feature, not a red flag. A spike can mean healthy new investment, or it can mean exactly what xz-utils saw: a new, unvetted contributor suddenly accounting for a large share of commits. The useful read isn't the raw commit count but the trendline relative to the project's own history, cross-referenced with who is committing. A 200-commit project that goes quiet for 14 months and then reactivates with 80% of commits from one new, previously unknown contributor is a different risk profile than the same drop followed by a return of the original maintainer.

What Other Proxies Matter Beyond Commits and Maintainer Count?

Issue and pull request response time matters as much as commit activity, because it measures whether the project can actually process a security report when one arrives. A project can have a healthy commit graph from dependency-bump bots and still take 90+ days to respond to a filed vulnerability, which is functionally the same risk as having no maintainer at all when a real issue lands. GitHub's own Octoverse and academic studies of OSS maintenance (including the Linux Foundation/Harvard "Census II" work on critical open source dependencies) have repeatedly flagged median response time and the ratio of open-to-closed issues as leading indicators that correlate with eventual abandonment.

A few other proxies worth tracking alongside bus factor:

  • Maintainer concentration (Gini-style): not just "how many people commit" but what share of commits the top contributor accounts for. A project with 12 contributors where one person made 95% of commits over the last two years has a bus factor much closer to 1 than the headcount suggests.
  • Funding and organizational backing: whether a project has a foundation, a company, or a Tidelift/Open Collective-style funding arrangement measurably changes maintainer retention. The 2021 Log4j crisis prompted the Apache Software Foundation and industry consortiums to fund critical logging infrastructure precisely because volunteer time had been the only thing standing behind a dependency used in an estimated hundreds of millions of Java deployments.
  • Release cadence versus outstanding CVEs: a project sitting on a disclosed, unpatched CVE for 6+ months with no released fix is a stronger signal than the CVE's CVSS score alone.
  • Dependency fan-in: how many downstream projects rely on this one. event-stream in 2018 was a mid-sized npm package (fewer than 2 million weekly downloads at the time) whose maintainer, feeling burned out, handed control to a stranger who added a malicious dependency, flatmap-stream, targeting a specific cryptocurrency wallet library. Low maintainer bandwidth plus high fan-in is the combination that turns a quiet handoff into a supply chain incident.

Can Bus Factor Be Gamed or Give a False Sense of Security?

Yes — a healthy-looking bus factor can still hide risk, because the metric counts people with access, not people who are actually paying attention. Adding a second or third maintainer with commit rights raises the numerical bus factor immediately, but if that person is inactive, newly added, or added specifically to pass a compliance checklist, the real-world resilience hasn't changed. This is exactly the shape of the xz-utils attack in reverse: Jia Tan's addition as co-maintainer technically improved the project's bus factor from 1 to 2 on paper, while in practice concentrating more control in the hands of the eventual attacker.

The inverse failure also happens: a project can have a bus factor of 1 and be extremely low risk because that one person is a well-resourced, full-time-paid maintainer backed by a company with succession planning, security response contracts, and code ownership documented for continuity. Bus factor is a proxy, not a verdict — it needs to be read alongside who the maintainer is, whether they're paid, and whether there's an organizational backstop, not treated as a pass/fail gate on its own.

How Do You Actually Calculate These Numbers for Your Dependency Tree?

You calculate bus factor and velocity by pulling commit, contributor, and issue-tracker history from the platform APIs (GitHub, GitLab, and equivalents) and computing contributor concentration over a trailing window, typically 12 to 24 months. In practice this means: total unique committers in the window, the percentage of commits from the top contributor, median time-to-close for issues tagged as security or bug, and days since the last commit and last tagged release. Academic tools like the "Bus Factor" project out of the SOM (Software Ownership Metrics) research community and industry scorecards such as OpenSSF Scorecard's "Maintained" and "Contributors" checks formalize versions of this calculation, but doing it manually across a dependency tree of hundreds or thousands of transitive packages — which is the actual size of most production applications — is not something a team can do check by check.

The harder part isn't computing one project's number, it's doing it at the scale of an SBOM: a mid-sized application easily pulls in 500-1,500 transitive open source dependencies, and the handful that matter most (highest fan-in, lowest bus factor, slowest response time) are buried among hundreds that are perfectly healthy.

How Safeguard Helps

Safeguard continuously scores the open source components in your software supply chain against the proxies above — bus factor, commit velocity trend, maintainer concentration, and issue response latency — and surfaces the ones that combine high usage with low resilience, rather than presenting a wall of undifferentiated dependency data. Instead of treating every transitive dependency as equally reviewable, Safeguard ranks risk by the same logic that made xz-utils and event-stream dangerous: a critical dependency, thin maintainership, and a quiet trendline that looks unremarkable until you compare it against the project's own history.

That risk view sits alongside Safeguard's SBOM, license, and vulnerability data so security and platform teams can act on maintenance risk before it becomes an incident report — flagging a bus-factor-1 package for a manual review, a pinned-version policy, or a vendoring decision, rather than discovering after the fact that the fix everyone needed was sitting on a maintainer's laptop with no one else able to ship it. Project health won't replace CVE scanning, but it answers the question CVE scanning can't: which of your healthy-looking dependencies are one departure away from becoming your next incident.

Never miss an update

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