How many times has Rails been downloaded
The honest answer is about 800 million, and the reason it is not a precise number is more interesting than the number.
Everything below came out of the RubyGems.org public API on 2026-10-12, which needs no key and answers immediately. The script that produces all of it is at the bottom and it was run to write this page.
The number
$ curl -s https://rubygems.org/api/v1/gems/rails.json | ruby -rjson -e 'puts JSON.parse($stdin.read)["downloads"]'
799556317
799,556,317 downloads of the gem named rails, since RubyGems.org started counting.
That is the number to quote if somebody asks. The rest of this page is why you should quote it with "about" in front of it.
Which gem is Rails
rails is a meta gem. It depends on the pieces and contains almost no code of its own, so counting
it counts the people who put gem "rails" in a Gemfile, and nothing else.
| Gem | Downloads | Against rails |
|---|---|---|
activesupport |
1,449,172,900 | 1.81x |
activerecord |
849,395,593 | 1.06x |
actionpack |
837,332,406 | 1.05x |
rails |
799,556,317 | 1.00x |
railties |
798,557,373 | 0.9988x |
Three of the five components have been downloaded more often than Rails itself, which is the
part worth sitting with. activesupport is nearly twice as popular as Rails, because a large part
of the Ruby ecosystem depends on it without being a Rails application: test frameworks, Sinatra
apps, standalone scripts that want 3.days.ago.
So "how many times has Rails been downloaded" has at least two defensible answers, 800 million and 1.4 billion, and they differ by a factor of 1.81 depending on where you draw the line around the word Rails.
railties is the useful one. It holds the framework's boot and generators, nothing depends on it
except Rails, and it comes in at 0.12 percent below rails. That near identity is a sanity check:
the two numbers were produced by the same installs.
Ruby and curl do not agree
This is the finding that decided how precise this page is allowed to be.
--- curl, no compression ---
799556317
799556317
--- curl --compressed ---
799552821
799552821
--- ruby, Net::HTTP ---
799552821
799552821
799552821
Same endpoint, same minute, two stable answers 3,496 apart.
The cause is one response header:
$ curl -sI https://rubygems.org/api/v1/gems/rails.json | grep -iE 'vary|age|cache-control|x-cache'
cache-control: max-age=60, public
age: 878
x-cache: HIT
vary: Accept-Encoding
vary: Accept-Encoding means the CDN stores a separate copy per encoding. Ruby's Net::HTTP sends
accept-encoding: gzip;q=1.0,deflate;q=0.6,identity;q=0.3 by default and curl sends none, so the
two clients land on two different cache objects, each ageing on its own clock. curl --compressed
moves curl onto Ruby's copy and the numbers match again.
The second header is the one that matters more. max-age=60 with age: 878 means the copy being
served is fourteen minutes old against a sixty second instruction. Any reading is a snapshot of
unknown staleness, and two readings taken a minute apart can go down, which is what happened
first and is what sent me looking.
None of this is a bug worth reporting. It is the ordinary behaviour of a cached public API, and it is the reason a download count is a magnitude rather than a measurement.
The shape of eight hundred million
521 versions are listed, 347 stable and 174 prereleases. Summed, they come to 799,551,451, which reconciles with the gem total to within about a thousand, the two having been read from different cache copies.
The distribution is not what you would guess.
| Version | Released | Downloads |
|---|---|---|
| 4.2.0 | 2014-12-20 | 41,175,739 |
| 7.2.2.1 | 2024-12-10 | 19,730,578 |
| 5.2.8.1 | 2022-07-12 | 16,048,107 |
| 4.2.9 | 2017-06-26 | 14,397,799 |
| 5.2.3 | 2019-03-28 | 14,071,707 |
| 5.1.7 | 2019-03-28 | 13,976,786 |
| 7.1.5.1 | 2024-12-10 | 12,922,594 |
| 8.1.3 | 2026-03-24 | 12,776,335 |
4.2.0 is 5.1 percent of every Rails download there has ever been, on its own, and it is more than twice the next entry. A single release from December 2014 outweighs the entire 8.1 line so far.
Two things produce that. Long lived applications pinned to a version keep redownloading it on every
cache miss for a decade, and 4.2 was the version a very large number of applications stopped on
before the 5.0 upgrade. The security patch releases clustering in the table, 7.2.2.1 and
7.1.5.1 both on 2024-12-10, are the same effect compressed: a CVE lands, every pipeline in the
world bundles on the same afternoon.
Which is also the warning. This column measures bundler activity, not adoption, and the two are only loosely related.
The dead end: the API does not know when Rails shipped
The obvious next question is when each version came out, and created_at looks like the answer.
It is not, for anything old:
-- the oldest numbers in the list --
0.8.0 created_at 2009-07-25
0.8.5 created_at 2009-07-25
0.9.0 created_at 2009-07-25
0.9.1 created_at 2009-07-25
Rails 0.8.0 was not released in July 2009. 46 of the 521 versions carry that exact date, everything from the 0.x line through 2.3.1, because that is the day RubyGems.org imported the back catalogue. Across 521 versions there are only 288 distinct dates.
So created_at is the date RubyGems.org learned about a version, which for everything from 2009
onward is also its release date, and for everything before it is one flat lie shared by 46 rows.
Any chart of Rails releases built from this field has a vertical wall in 2009 and nothing before it.
For dates before 2009 the API is the wrong source, and the tags in rails/rails are the right one.
From 2019 onward the field is trustworthy, which is what makes it usable for the question people
actually ask of it: When is Rails 8.2 coming out.
What a download is not
Worth saying plainly because the number invites the wrong conclusion.
It is not users, it is not applications, and it is not installs. It is one HTTP fetch of a .gem
file. Every CI run with a cold cache counts. Every docker build without a mounted bundle counts,
once per layer rebuild. Every corporate mirror that pulls the whole index counts. A single team
deploying forty times a day can generate more downloads in a week than a hundred hobby projects
generate in a year.
The number is real, large, and tells you that Rails is widely used. It does not tell you how widely, and nobody has that number.
The script
Every figure above comes out of this. It needs no credentials.
require "net/http"
require "json"
def api(path)
JSON.parse(Net::HTTP.get(URI("https://rubygems.org/api/v1/#{path}")))
end
%w[rails railties activesupport activerecord actionpack].each do |name|
gem = api("gems/#{name}.json")
printf("%-14s %15s latest %s\n",
gem["name"],
gem["downloads"].to_s.reverse.scan(/\d{1,3}/).join(",").reverse,
gem["version"])
end
versions = api("versions/rails.json")
summed = versions.sum { |v| v["downloads_count"] }
top = versions.max_by { |v| v["downloads_count"] }
puts
puts "versions listed #{versions.size}"
puts "sum of every version #{summed}"
puts "biggest single version #{top['number']} at #{top['downloads_count']} " \
"(#{(100.0 * top['downloads_count'] / summed).round(1)}%)"
puts "distinct created_at #{versions.map { |v| v['created_at'][0, 10] }.uniq.size}"
puts "oldest created_at #{versions.map { |v| v['created_at'][0, 10] }.min}"
Run it and the totals will not match this page, because the counter moves and because your HTTP client decides which cached copy you get. That is the point.
What this page does not cover
Nothing here is adoption. The RubyGems API counts fetches and has no opinion about how many applications are running, how many developers are employed on them, or how that compares to any other framework, and the download counts of two ecosystems are not comparable at all: npm packages are fetched per dependency tree per install, which inflates them against a Ruby meta gem by orders of magnitude.
The per day and per version time series that would show whether that 800 million is still growing
is available from a different endpoint and was not touched, so this page is a level and not a trend.
Nothing was read from rails/rails itself, so the pre 2009 release dates named as missing above
are named as missing and were not recovered.
Comments
No comments yet. Be the first.