Skip to content

Instantly share code, notes, and snippets.

View jpcamara's full-sized avatar

JP Camara jpcamara

View GitHub Profile
@jpcamara
jpcamara / README.md
Created October 10, 2026 11:49
Ractors on Ruby master collect thousands of extra times since abac51a1ce

Ractors on Ruby master collect thousands of extra times since abac51a1ce

Per-Ractor GC (Feature #22227) is a big win. On a 16-thread box, JSON parsing in 16 Ractors went from 13.6x slower than one Ractor to 2.2x. Fork gets 2.9x. While benchmarking it I found that a single Ractor got slower again on later master. Fork and the main Ractor didn't.

When it happened

abac51a1ce,

Each step was A/B tested against the commit just before it (requests/sec at 16 clients, median of 3–5 alternating reps). Every step had its own baseline, so the percentages don't multiply into the totals exactly. A dash means no notable change on that route.

Change Room Messages Sidebar Search Post
No Rack::Deflater, Redis compress: false, no Rack::ETag, 4 workers (measured together) +56% +52% +19% +31% +19%
Puma → Falcon +1% +3% +10% +12% +1%
Static-file checks skipped + tags once per process + Current.account once (together) +10% — +14% +14% —
Per-process fragment copies + cache versions without a DB checkout (together) +13% +20% +6% +8% —
Run with ruby-3.4.0-preview2
- gem install falcon
- RUBY_YJIT_ENABLE=1 falcon serve --bind http://localhost:4001 --count 1 -c chat_server.ru
- bun run chat-client.mjs
Connecting 32 WebSocket clients...
[186.53ms] All 32 clients connected
230567 messages per second (32 clients x 1600 msg, min delay: 64ms)
239922 messages per second (32 clients x 1600 msg, min delay: 64ms)
271556 messages per second (32 clients x 1600 msg, min delay: 64ms)
# first window
bundle install
bundle exec bento --falcon
# second window
make wsdirector # works
SCENARIO=broadcast make wsdirector # works
make anyt-falcon # works
# In your Gemfile
gem "localhost"

# Then, depending on your desired server
gem "falcon"
gem "puma"
# hangs, same as MN threads
# RUBY_MN_THREADS=1 make test-all TESTS="--name=TestIO#test_open_fifo_does_not_block_other_threads"
require "tempfile"
require "async"
def mkcdtmpdir
Dir.mktmpdir {|d|
Dir.chdir(d) {
yield