How fast can you actually patch Ruby?
- Name
- Dennis Paagman
- @djfpaagman
When I tried to update an app to Ruby 4.0.9 last Friday, the official Docker image wasn’t available yet. The release fixed vulnerabilities GitLab had found, but I had to wait before I could deploy.
A few months ago, a government Rails site was hit by an ActiveStorage vulnerability eight hours after the patch went out. Last week, PHP2Shell was being exploited before it was announced.1 Waiting for a Docker image can eat up the time you have to respond.
When Ruby 4.0.9 became available
I took every installer and version manager listed on the official installation page on ruby-lang.org, then added container images, CI providers and hosting platforms I could think of. For each, I checked when 4.0.9 became available.2
All times start when the Ruby 4.0.9 source tarball became available, on Friday 23 October 2026, 04:04 UTC.3
Installers and version managers
| Resource | Available after |
|---|---|
| ruby-build (rbenv, and mise when compiling) | 43 m |
| ruby/ruby-builder binaries | 48 m |
| Homebrew ruby-build | 1 h 10 m |
| asdf | 2 h 43 m |
| jdx/ruby binaries (mise’s precompiled Rubies) | 8 h 15 m |
| RubyInstaller (Windows, also RVM 4 Windows) | ⚠️ 16 h 35 m |
| RVM | ⚠️ 18 h 34 m |
| rv | ⚠️ 21 h 40 m |
| ruby-install | ❌ metadata still on 4.0.74 |
| chruby | Depends on the installer used5 |
| rbenv for Windows | ❌ last updated to 4.0.1 in March |
Container images
| Resource | Available after |
|---|---|
| rubylang/ruby (by the Ruby core team) | 8 m |
| bitnami/ruby | 1 h 59 m |
| ruby (by Docker) | ⚠️ 15 h 57 m |
CI
| Resource | Available after |
|---|---|
| GitHub Actions setup-ruby (Linux/macOS) | 1 h 12 m |
| CircleCI cimg/ruby | 1 h 36 m |
| GitHub Actions setup-ruby (Windows) | ⚠️ 28 h 34 m |
Hosting platforms
| Resource | Available after |
|---|---|
| Heroku | 2 h 28 m |
| Railway (uses mise) | 8 h 15 m |
| Fly.io, Kamal and anything else using the official Docker image | ⚠️ 15 h 57 m |
| Google Cloud (Cloud Run, App Engine) | ⚠️ ≈ 3 d 14 h, default still 4.0.7 |
| AWS Lambda | ❌ still on 4.0.7 |
| AWS Elastic Beanstalk | ❌ still on 4.0.7 |
| DigitalOcean App Platform | ❌ docs say 4.0.1–4.0.2 |
System packages
| Resource | Available after |
|---|---|
| Snap | 7 m |
| Homebrew | 2 h 41 m |
| nixpkgs | 3 h 47 m |
| Fedora (Rawhide; 44/45 still in testing) | ⚠️ 11 h 03 m |
| winget | ⚠️ 20 h 54 m |
| Debian, Ubuntu, Alpine, Arch | ❌ no Ruby 4 at all |
What stands out
- The fastest ones are really fast, and mostly come from Ruby itself. The Snap package and the
rubylang/rubyimage are both published by the Ruby core team, and were available after 7 and 8 minutes. A bot committed the ruby-build definition 28 seconds after the tarball was uploaded, and the ruby-build release followed at 43 minutes. - The official Docker image took almost 16 hours.6 The Dockerfile Rails generates uses this image, so it’s also what you get with Kamal and Fly.io by default.7 The Dockerfile itself was updated about seven hours after the tarball appeared. Most of the wait came after that, in the official-images review and build pipeline. That review serves a purpose, but it also adds hours to the wait for a security patch.
- Some platforms are even slower. AWS Lambda and Elastic Beanstalk are still on 4.0.7, DigitalOcean’s docs list 4.0.1–4.0.2, and Google Cloud took about three and a half days to publish a 4.0.9 image, while its default for Ruby 4.0 is still 4.0.7. If you rely on a provider’s Ruby runtime, you depend on its update schedule.
Your pipeline is your response time
Your version manager, CI and production environment all need to support the new version before you can roll it out. The slowest one decides how fast you can patch.
Some things you can do before the next Ruby security release:
- Check the whole path to production. Find out how your local version manager, CI and production environment pick up new Ruby releases. Look for a manual approval, a scheduled build or another step that could hold up an update.
- Automate the boring part. Let a bot pick up new versions of your dependencies (Ruby, your gems and your base image), run CI and deploy when everything is green. The fewer manual steps, the faster you’re patched.
- Choose a hosting setup that lets you patch promptly. I’d avoid relying on a provider’s Ruby runtime if it’s still two patch versions behind. Use a custom container where supported, so you can update Ruby on your own schedule.
Spare a thought for the maintainers
All of this puts extra pressure on the maintainers of these tools, and most of them are volunteers. Every patch release means a chain of PRs, reviews, builds and releases across dozens of projects. The expectations keep going up.
The fastest ones show how much of that work bots can take over, so maintainers don’t have to drop everything for every release.
So a big thank you to everyone who makes this happen, often within minutes. 🙏
-
Amazon’s honeypots saw the first attempts four days before disclosure. ↩
-
Availability was checked through October 27. Most timestamps are Git commit dates or GitHub release dates. For Docker images I used Docker Hub’s last pushed date; for Heroku, the S3
Last-Modifiedheader. For Homebrew it’s the bottle commit. For Google Cloud I used the upload time of theruby:4.0.9runtime image in Artifact Registry. For AWS Lambda I checkedruby -vin thepublic.ecr.aws/lambda/ruby:4.0image. ↩ -
The v4.0.9 tag was pushed at 02:36 UTC, 1 h 28 m before the tarball appeared on cache.ruby-lang.org. The announcement post followed 34 minutes after the tarball. The fixes themselves were public even earlier as regular commits in the Ruby repository, and some were already part of 4.0.8. I use the tarball upload to measure how quickly downstream tools packaged the release. ↩
-
ruby-install gets its version list and checksums from postmodern/ruby-versions. This row tracks that metadata. ruby-install also supports explicit versions, custom source URLs and checksums, so you can supply the release tarball URL and its official checksum before the metadata is updated. ↩
-
chruby switches between installed Rubies and doesn’t require an update for each release. Its documentation covers manual installation and using either ruby-install or ruby-build. With ruby-build, the release was available after 43 minutes; you could also compile the tarball yourself. ↩
-
What counts as ‘official’ is a bit confusing here.
rubyis a Docker Official Image maintained by Docker, whilerubylang/rubyis published by the Ruby core team itself. ↩ -
Docker Hub shows ~1.59 billion pulls for
rubyand ~3.5 million forrubylang/ruby. The image that took 15 h 57 m has about 450 times as many pulls as the one available after 8 minutes. ↩
I've got some availability for new clients! If you're looking for someone with 15 years of Rails experience and a deep feel for Hotwire, who's all in on building with AI agents, let's chat.
Get in touch