# GitHub Actions vs Jenkins: counting what you would maintain

> GitHub Actions vs Jenkins with the catalog counted: 2,111 plugins in the update center, 767 with a published security warning, 267 marked deprecated.

Source: https://latchkey.dev/learn/runners/github-actions-vs-jenkins-compared  
Updated: 2026-09-21

GitHub Actions vs Jenkins is almost always argued as flexibility against maintenance, and the maintenance side is usually left as a feeling. It is measurable: the Jenkins update center currently distributes 2,111 plugins, carries 1,567 published security warnings of which 1,512 name a plugin, and marks 267 plugins as deprecated.

Jenkins is an automation server you run: a controller, some agents, a Java runtime and whatever plugins your pipelines depend on. It is the most flexible thing in this comparison and it will do jobs no hosted CI will, because you own every layer of it.

GitHub Actions is a hosted control plane with runners underneath, coupled to GitHub repositories. You do not own the layers, which is both the limitation and the point.

The numbers below were read on 21 September 2026 from the Jenkins update center data that a Jenkins install itself consumes, from the plugins.jenkins.io API, and from the Jenkins LTS changelog, alongside GitHub's billing and limits references. They describe the catalog, not any one installation.

## Comparison

|  | GitHub Actions | Jenkins |
| --- | --- | --- |
| What you run | Nothing. Optionally self-hosted runners | A controller plus agents, on a Java runtime. The installation docs require Java 21 or later |
| Release cadence you track | None. The service updates itself | A weekly line, currently 2.582, and an LTS line chosen every 12 weeks from it, currently **2.568.3** released 2 September 2026 |
| Extension catalog | Actions pinned by tag or commit SHA, resolved per workflow run | **2,111 plugins** in the update center, installed into the controller and upgraded with it |
| Catalog health | Not applicable | **767 of those 2,111** plugins carry at least one published security warning against some version range, and **267** are marked deprecated |
| Pipeline language | YAML, with reusable workflows and composite actions | A Jenkinsfile in a Groovy domain-specific language, in either Declarative or Scripted syntax |
| What you pay per minute | $0.006 at 2 vCPU on Linux, or $0.0025 on a managed runner at the same size | Nothing for the software, which is MIT licensed. The controller and every agent bill whether or not a build is running |
| Included allowance | 2,000 minutes a month on Free, 3,000 on Team, 50,000 on Enterprise Cloud, and free and unlimited on public repositories | Not applicable |
| Where the code can live | GitHub only. Actions is not a general automation server | Anywhere. This is the strongest argument for Jenkins and it is rarely the one people give |
| Self-healing or retries | None on GitHub-hosted runners; transient failures diagnosed and retried inside the run on Latchkey | Whatever a plugin gives you, which means another plugin to keep current |
| Setup change required | A file in the repository | A controller, agents, credentials, plugin selection, and a Jenkinsfile per repository |

## What the catalog numbers do and do not say

Read them precisely, because the obvious misreading is worse than useless. A security warning in the update center names a plugin and the version range it applies to, and the overwhelming majority were published alongside a fix. So 767 plugins carrying at least one warning does not mean 767 plugins are unsafe today. It means 36% of the catalog has needed a security fix at some point, which is a measure of how much maintenance the extension model generates rather than a measure of present danger.

That is still the number that belongs in the decision, because the work a warning creates does not go away when the fix ships. Somebody has to notice the advisory, work out whether the installed version is inside the affected range, check the upgrade against the other plugins that depend on it, and schedule a controller restart. Multiply by a plugin list of twenty or thirty and you have described a recurring job that nobody was hired to do.

The 267 deprecated plugins are the other half of the same story and are easier to act on: a deprecated plugin will not be fixed, so anything you depend on that appears on that list is work already scheduled, whether or not it is on a roadmap.

## The upgrade treadmill, with its cadence published

Jenkins publishes both lines, so the cadence is not a guess. A long-term support release is chosen every 12 weeks from the stream of weekly releases; the current LTS is 2.568.3, published on 2 September 2026, and the weekly line had reached 2.582 by 20 September. The LTS changelog also records the tested configurations for each release, currently Linux and Windows on JDKs 21 and 25.

Every one of those numbers is a thing you track on a Jenkins install and do not track on Actions. That is the whole managed-versus-self-hosted trade restated in version numbers, and it is worth saying plainly because teams tend to price the server and forget the calendar.

The flip side is real and deserves equal space. Nothing in the GitHub Actions model lets you pin the platform, roll back the control plane, or decline an update. If an Actions behaviour changes under you, the recourse is a support ticket. On Jenkins the recourse is not upgrading, which is a form of control that a regulated environment sometimes genuinely requires.

## Speed

Not benchmarked yet, and a benchmark would mostly measure hardware. A Jenkins agent and a GitHub runner both end up executing your build script on a Linux box; the difference in wall clock comes from what is cached on that box and how big it is.

The one structural difference worth naming is where cache warmth comes from. Long-lived Jenkins agents accumulate state between builds, which is why a Jenkins pipeline can feel fast and why a migration to ephemeral runners often feels slow until dependency and Docker layer caching are configured explicitly. That is not the platform being slower; it is a free accident of statefulness that ephemeral runners require you to arrange on purpose.

## Cost: free software with a salary attached

Jenkins is MIT licensed and costs nothing to install. The bill is a controller that runs continuously, agents sized for peak, storage for build history, and the time of whoever owns all of it. That last line is the one that decides most migrations, and it is the one that never appears on a cloud invoice.

The comparison on the Actions side is a single multiplication. Ten thousand Linux minutes a month is $60 at GitHub's $0.006 list rate for 2 vCPU, $42 on a Team plan after the 3,000 included minutes, or $25 at $0.0025 a minute on a managed runner at the same size. If your Jenkins estate is a controller and two agents on always-on instances, the honest question is not which is cheaper in dollars but what fraction of an engineer the difference buys.

## Why there is no recorded run on this page

The claim this page rests on is about a catalog rather than a build. It was checked by reading the same update center file a Jenkins controller downloads to decide what to offer you, and counting the entries in it. Standing up a controller and recording a green build would demonstrate that Jenkins runs builds, which nobody disputes, and would say nothing about 2,111 plugins. The counts are reproducible from the public update center data in one command, and the source is linked below.

## When to keep Jenkins

- The code is not on GitHub. Actions is coupled to GitHub repositories and is not a general automation server, so this ends the discussion rather than starting it.
- Builds are triggered by things that are not repository events: artifact repositories, issue trackers, hardware, external schedulers.
- Compliance requires that no code or build artifact leaves your own infrastructure, and self-hosted runners are not an acceptable half-measure.
- You have shared Groovy pipeline libraries that a team actively maintains and that encode real logic rather than workarounds. Rewriting those is the largest line in any migration estimate.
- You need to decline platform updates. A pinned Jenkins is a supported state; a pinned Actions control plane is not a thing that exists.

## When to move

- The code is already on GitHub and the CI config should live beside it, with pull request checks and deployment gates as first-class objects rather than as plugins.
- The plugin list is the maintenance. If your upgrade window is dominated by compatibility checks, you are paying for flexibility you are not using.
- Nobody owns the controller. A CI server that one person knows how to restart is an availability risk with a name on it.
- You are about to scale agents by hand as headcount grows, which is the problem managed runners exist to delete.

## The verdict

Jenkins earns its reputation in both directions. It will automate anything, from any trigger, on any hardware, and it is the only option in this comparison that does not care where your code is hosted. It also asks you to track two release lines, maintain a Java runtime, and own a plugin catalog where 767 of 2,111 entries have needed a published security fix and 267 will never get another one. If your code is on GitHub and your pipelines are ordinary builds, tests and deploys, Actions removes that entire layer and the flexibility you give up is flexibility you were not using. If your code is not on GitHub, or your triggers are not commits, keep Jenkins and spend the argument on something else.

## FAQ

### How many Jenkins plugins are there?

The update center distributed 2,111 plugins when this page was written on 21 September 2026, which is the same list a Jenkins controller downloads to decide what it can offer you. Of those, 767 carry at least one published security warning against some version range and 267 are marked deprecated.

### Does a security warning mean a Jenkins plugin is unsafe?

Not necessarily. A warning names the affected version range, and most are published together with a fixed release, so an up to date plugin with a historical warning is usually fine. The count is a measure of how much of the catalog has needed a security fix rather than of how much is currently vulnerable, and the work it represents is the triage rather than the risk.

### How often does Jenkins release?

Weekly, with a long-term support release chosen every 12 weeks from that stream. The current LTS is 2.568.3, published on 2 September 2026, and the weekly line had reached 2.582 by 20 September 2026. Each LTS entry records its tested platforms and JDKs, currently Linux and Windows on JDKs 21 and 25.

### Do I have to rewrite my Jenkinsfiles to move to GitHub Actions?

Yes. A Jenkinsfile is a Groovy domain-specific language in Declarative or Scripted syntax, and neither translates mechanically to Actions YAML. The conceptual mapping is quick to learn: stages become jobs, the agent becomes `runs-on`, and a shell step becomes `run`. Shared Groovy libraries are the part that takes real time.

### Is GitHub Actions a full replacement for Jenkins?

For teams whose code is on GitHub and whose builds are triggered by commits, it covers the same ground with no server to own. It is not a replacement when the repositories are elsewhere, when builds are triggered by systems that do not emit repository events, or when the requirement is to control exactly when the platform changes underneath you.

## References

- [The Jenkins update center data, which is where the plugin and warning counts come from](https://updates.jenkins.io/current/update-center.actual.json)
- [Jenkins LTS changelog, read for the release cadence and tested configurations](https://www.jenkins.io/changelog-stable/)
- [Jenkins documentation: installing on Linux, including the Java requirement](https://www.jenkins.io/doc/book/installing/linux/)
- [GitHub Actions runner pricing, read for the per-minute rates quoted here](https://docs.github.com/en/billing/reference/actions-runner-pricing)

---

Latchkey runs CI/CD that repairs its own failures. Agent entry points: https://latchkey.dev/agent.txt, https://latchkey.dev/openapi.json, https://latchkey.dev/llms.txt
