Normally I just fire off a tweet when I spot a nice performance PR landing in Ruby. Lately I've been catching up on a backlog of Ruby performance work I'd bookmarked and never gotten around to - so some of what's below isn't brand new, with a few PRs dating back to 2025. There were so many of them - some headline-grabbing, some small but delightfully clever - that a thread won't cut it. So here's a roundup instead, both the recent landings and the ones I'm late to.
A few ground rules: every PR below ships a concrete benchmark number, so when I say "Nx faster" it's the author's own measurement, not vibes. Numbers come from different machines and workloads, so treat them as "here's the win on the benchmark that motivated the change," not cross-comparable lab results. Click through to any PR for the full picture - most authors document their methodology beautifully.
Let's go.
Strings & text
String#scrub skips ASCII runs - Instead of decoding a string character-by-character, scrub now jumps over ASCII runs using the same search_nonascii trick valid_encoding? uses. On English HTML it's up to 45.55x faster, on Japanese HTML 22.71x, and ~3.5x on the general case - with no regression on the worst case. Beautiful work by FletcherDares, who's been on a string-performance tear.
String#codepoints ASCII hot path - Same author, same instinct: add a local fast path for ASCII bytes inside mostly-ASCII UTF-8 strings. Result: ~1.9x faster on mixed ASCII content, neutral on pure multibyte.
String#gsub! stops copying on no-match - gsub! was eagerly copying shared backing storage even when nothing matched. Defer that copy until the first real match (like sub! already does) and you get 2.33x faster no-match calls - and the allocation on a 100k-char shared string drops from 100,041 bytes to 40 bytes.
Files & directories (the byroot file-IO spree)
byroot (Jean Boussier) went on a tear through Ruby's file primitives, and the numbers are spicy:
File.join common case - Optimistically handle the common "two UTF-8 strings" case and scan backwards for the separator. Up to 18.81x faster for many-string joins, 7.80x for two strings.
Dir.scan yields entry type - Yield each child's type straight from struct dirent's d_type, avoiding a separate stat per child. Recursive directory walks come out 2.12x faster ("twice as fast").
dir.c caches the working directory - Cache and cheaply revalidate pwd with a stack buffer instead of always heap-allocating. Up to 1.33x faster Dir.pwd on Linux.
GC & object allocation
Clear page bits in one shot - jhawthorn (John Hawthorn) turned age bits into a bit plane so age + wb_unprotected bits clear for a whole 64-slot page at once during sweep. ~14% off object-new.
Move rb_class_allocate_instance into gc.c - Also jhawthorn: relocating the function lets allocation helpers inline with newobj. ~10–15% faster Object.allocate (1.15x).
Remove the class alloc check - jhawthorn again, demoting a runtime allocation-class check to a debug-only assert and unlocking tail-call optimization. ~10% faster Object.new (1.12x).
Concurrency & core classes
Speed up TypedData_Get_Struct - byroot added an inlinable fast path to rb_check_typeddata, which makes Mutex#synchronize and Monitor#synchronize ~1.54x / ~1.55x faster respectively.
Thread::Queue uses a ring buffer - Swapping the backing array for a ring buffer removes array-function overhead: ~23% faster (1.24x). byroot.
Give the hot thread scheduler priority - jpl-coconut reworked thread switching to avoid an intermediate monitor-thread hop. On a 2-core setup the motivating benchmark went from 1.455s to 0.231s (and a heavier scenario from 36.7s to 4.1s).
Parser & build
Parallelize bundled gem tests - Not a runtime win, but st0012 (Stan Lo) made CI run gem tests through a thread pool tied into the make jobserver, shaving ~40% off that CI step across platforms.
Prism parser optimizations - kddnewton (Kevin Newton) packed in fast/slow path splitting, scope bloom filters, SIMD/SWAR strpbrk, a wyhash word-at-a-time constant pool, and a parser arena. ~22% faster parsing at roughly the same memory. (The matching ruby/ruby side is #16418.)
Optimize the Prism Ruby visitor - Replace the array-allocating compact_child_nodes with an each_child_node that yields directly. Visiting the Rails codebase came out ~21% faster on the interpreter and roughly 2.3x faster under YJIT.
Lazily deserialize DefNode - Defer DefNode deserialization in the Java loader so JRuby/TruffleRuby don't pay for method bodies up front: ~1.5x faster on the parsing-core metric.
BigDecimal goes brrr
tompng (Tomoya Ishida) has been quietly doing extraordinary things to BigDecimal:
NTT multiplication + Newton-Raphson division - O(n log n) multiplication via a three-prime Number Theoretic Transform. The headline is almost comical: up to 800,000x faster multiplication. A squaring that was estimated at 270 days now runs in 29 seconds. This is the kind of PR you frame on a wall.
Increase VpMult batch size - Bumping the divmod batch from 8 to 16 makes mid-size multiplications ~1.8x faster. tompng.
Optimize BigDecimal#to_s - byroot replaced two snprintf calls with a lean integer-to-ASCII routine: ~2.6x faster for small numbers, ~3.8x for large ones.
JIT corner
Fix RCLASS_EXT_WRITABLE perf - luke-gruber swapped FL_TEST/FL_SET for their _RAW variants, dropping a YJIT getivar benchmark from 60ms to 40ms (~1.5x).
Rewrite Array#find in Ruby - swebb reimplemented Array#find in Ruby so the JIT can chew on it: ~1.96x faster under YJIT, neutral on the interpreter.
ZJIT recompiles getivar on shape-guard failure - k0kubun (Takashi Kokubun) cut guard_shape_failure side exits on the lobsters benchmark from 22.5% down to 3.0%, keeping more code in ZJIT.
Annotate Float predicates - Teaching ZJIT about Float#nan? / finite? / infinite? lets it emit the fast C-call path: ~21–27% faster on those predicates in a tight loop.
Optimize Lrama - the parser generator gets faster, cutting Ruby's own parse.y processing from 2.84s to 1.60s (~1.78x).
Closing
If you like performance magic, go read these. And if you maintain a gem, read them twice - a lot of what's here (back-to-front scanning, single-byte fast paths, deferring copies, avoiding stat) is worth learning from.
I just returned from RubyKaigi 2026, held from April 22nd to 24th in Hakodate, Hokkaido. For those unfamiliar with it, RubyKaigi is the biggest Ruby conference in the world, drawing speakers, committers, and Rubyists from across the globe. As always, it managed to combine deep technical talks with a uniquely Japanese atmosphere that no other conference comes close to.
This year's edition had a distinctly Hokkaido feel: the cold winds of the northernmost island, the smell of the sea, kaiseki dinners, sashimi at conference parties, and onsens - a lot of onsens. The conference itself was in the south of Hokkaido (Hakodate). Still, for me, the trip extended significantly further north and east thanks to my Japanese friend Hasumi Hitoshi, who once again made my Japan adventure something far beyond just a conference visit.
What I love most about RubyKaigi is how it bridges the gap between the Japanese and Western Ruby worlds. Despite Ruby coming from Japan, these two communities still feel oddly separate in day-to-day work - both reinventing the wheel from time to time, both not drawing as much from each other as we should. RubyKaigi is the rare place where these worlds collide. You meet the people whose code you've used for years, you hand them a beer, and suddenly Ruby's global ecosystem feels a bit more whole.
Pre-Conference: Tokyo Stopover and Heading North
My journey started in Tokyo, where I landed early in the morning. Passport control took 40 minutes, unusually long, but otherwise the trip was smooth. With a couple of hours to kill before my Shinkansen to Hakodate, I wandered around Tokyo Station and walked through the park near the Imperial Palace. There's something about Japanese parks that always gets me - even ten minutes from a major train station, the city noise disappears.
The Shinkansen ride was uneventful, but the local train from Shin-Hakodate to Hakodate brought an unexpected moment: an earthquake alarm went off mid-ride. Shortly after we pulled into Hakodate Station, tsunami sirens started wailing across the platform. But not a single Japanese person around me was panicking or evacuating, so I figured everything would be fine. It was. Welcome to Japan.
Day 0 - Hakodate Settling In
I arrived in Hakodate, settled into my hotel (which had its own quirks: a glitchy speaker playing a melody on loop and a wheezing AC unit), and did what any jet-lagged traveler does on day one: I slept. About 15 to 16 hours, with one break for breakfast.
Day 0 also brought the ANDPAD Welcome Drinkup, the unofficial kickoff for many of us. Roughly a hundred people crammed into Jimotoya, a local izakaya with great food.
The Conference Experience
Day 1 - Tagomori, Hasumi, and the Wind
The conference opened with Satoshi Tagomori's keynote on Box, his ongoing work on namespacing in Ruby. As I wrote about last year regarding namespaces, I have strong reservations about the feature. My core concern remains: until the surrounding ecosystem (RubyGems, Bundler) properly supports it, releasing Box risks fragmenting the Ruby ecosystem in ways we'll spend years cleaning up.
That said, Tagomoris absolutely deserved this keynote slot. The scope, the thinking, the engineering rigor, and the fact that he's willing to engage with critics (including me) about hard tradeoffs all make him one of the people I most respect in this community. I love this guy. I don't love this particular feature, at least not yet.
Later that day, Hasumi Hitoshi delivered his PicoRuby talk. Each year, I'm more impressed with how fast PicoRuby is evolving. Running Ruby on IoT devices used to feel like a curiosity; now it has serious, real-world use cases. There were noticeably more PicoRuby-related talks at this year's RubyKaigi, which suggests where the community sees this going. Hasumi-san's work on this, alongside PRK Firmware, IRB, and Reline, continues to be foundational for a whole subset of the Ruby world that doesn't always get the spotlight at major conferences.
The day wrapped with the RubyKaigi 2026 Official Party. The Japanese style of holding the official party in a hotel always slightly surprises me at first - back home, we'd probably do this kind of event in a pub or bar that had been reserved entirely for us - but late April in Hokkaido makes the indoor decision obvious. Big plus for the beer selection, which was excellent.
I stayed out until 1 am, wandering through Hakodate with a great group. The city, which on first impression I'd written off as a slightly run-down outpost, was already starting to grow on me. The wind, on the other hand, was absolutely brutal: without my winter hat, my head would have fallen off.
Day 2 - Nutter, Zhu, Tenderlove, and My Talk
Day 2 was, for me, the strongest technical day of the conference.
It opened with Charles Nutter's keynote on JRuby's history. This was well executed, presented as a journey rather than a lecture, packed with anecdotes, and giving real credit to all the people who built JRuby over the years. It's genuinely a bummer that Charles still has to spend time explaining what JRuby is to newcomers; given its capabilities, JRuby should be far more mainstream in many use cases than it actually is. The work he and the JRuby team do is impressive, and this talk did a great job of contextualizing it within the broader Ruby story.
Next came Peter Zhu with his talk on the next-generation GC for Ruby. Two things I always say about Peter: first, he delivers from both a presentation and a content standpoint; his talks are dense without being overwhelming. Second, his work on CRuby's GC is genuinely among the most important infrastructure work in our community right now. He laid out a clear roadmap and walked through the technical motivation. Easily one of my favorite talks of the conference.
Then Aaron Patterson took the stage to talk about faster FFI. I've been spending significant time recently rewiring large parts of Karafka and rdkafka-ruby to reduce the number of crossings between Ruby and C via FFI. Every transition has overhead, and at Karafka's scale, it adds up fast. Watching Aaron work on the language side of the same problem was encouraging. I plan to set up a stable benchmarking machine for the Karafka ecosystem, and I hope Aaron's work will eventually appear in those benchmarks.
A side note worth making explicit, every year: the RubyKaigi translation team is incredible. Simultaneous interpretation between Japanese and English is one of the things that make this conference uniquely accessible, and the people doing that work rarely get the credit they deserve. Thank you.
My Talk - Ractors in Karafka, in Production
Like in 2025, I want to give my own talk its own short section.
I spoke about using Ractors in production in Karafka. The hardest part of giving this talk was that while I was talking about my actual implementation of Ractor support in Karafka, I was also discussing Ractors themselves, which I obviously didn't implement and which still have well-known limitations.
The feedback was good, including from members of the Ruby Core Team, which mattered a lot to me. The core message I wanted to land was: Ractors, even with their current limitations, have a real, workable niche today, and they can be used in production. This is the chicken-and-egg problem we have to break. If no one uses Ractors because they're limited, no one will provide the production data the core team needs to improve them. Someone has to go first.
The slides are available below.
After the talks, the evening continued with the Treasure Data Hakodate Night Drinkup on the Tram. Big shout-out to Treasure Data for one of the most creative event ideas I've seen at any conference: a tram filled with sake and beer, wandering through Hakodate. I have a soft spot for this kind of slightly-crazy execution. Met some great people, had excellent sake, and capped it off with one more drink at a hotel bar with a group of Japanese Rubyists.
The night, however, kept going. I ended up at one of those tiny, deeply local izakayas: six chairs, paper menus in Japanese only, no prices, and one older man behind the counter, grilling yakitori on a tiny, smoking grill. ¥100 a stick. I had six. They were excellent. I will never understand the economics of these places, how a tiny restaurant with capacity for one Japanese regular and one bewildered tourist stays in business. Still, I am eternally grateful that they do. My jacket smelled like a campfire for the next 48 hours, and it was worth every minute.
Day 3 - John Hawthorn and Hunting GC Bugs
Day 3 brought John Hawthorn's talk on Write Barriers, which hit close to home. I ran into a brutal write-barrier-related issue in 2025, which I documented in detail in When Your Hash Becomes a String: Hunting Ruby's Million-to-One Memory Bug. If you've never had to debug a GC issue in production where a Ruby Hash somehow turns into a String, count yourself lucky.
It's encouraging to know that people are working to improve GC-related tooling, because anyone who has hunted for these bugs understands the unique pain of debugging something that, by definition, only manifests when the runtime is doing something invisible to the user. John's talk was a great roadmap, and I felt every second of the GC-debugging journey he described.
The Hallway Track
Before moving on, I want to call out something that doesn't appear on any official schedule but is the single most important part of every RubyKaigi: the hallway track. The conversations between sessions, in the lobby, over coffee, at the booths, in the food line - that's where actual collaboration happens.
If you ever make it to RubyKaigi, please don't try to attend every talk. The talks are recorded. The hallway track isn't.
The Evening Events - Thanks to the Sponsors
On Day 3 evening, before the post-conference adventures began, I attended a few more drink-ups. There are so many sponsored events at RubyKaigi that you genuinely can't go to all of them, and one of the highlights of every Kaigi is choosing which ones to drop into.
I want to thank the sponsors who made these events possible. Across the conference, I either attended or benefited indirectly from events organized by:
ANDPAD Inc. - Welcome Drinkup (Day 0) and Code Party (Day 2)
The RubyKaigi 2026 organizing team - the Official Party (Day 1)
All the smaller drinkups across Days 1-3 from STORES, Hello Inc., IVRy, Leaner Technologies, ESM, CodeCast, note inc., Findy, Studist, OPTiM, giftee, Coincheck, GMO Internet Group, hacomono, Link and Motivation, mov, freee, pixiv, Net Protections, and many more I'm probably forgetting.
These events are what turn RubyKaigi from a conference into a community.
Post-Conference Adventures with Hasumi-san
Now for the part that, as in 2025, ends up being almost as important as the conference itself: the trip after.
This year, I had the enormous privilege of being invited by Hasumi-san for a road trip through Hokkaido. He had planned the route, organized the rental car, arranged accommodations, and generously shared his time over multiple days to show me parts of Hokkaido I would never have seen on my own. None of this would have happened without him. Thank you, Hasumi-san. 🙏
Hokuto, Futamata Radium Spa, Soba in Makkari, and Lake Hangetsu
We rented a car after the conference and drove first to Hokuto for the cherry blossoms. From there to Futamata Radium Spa (二股ラヂウム温泉旅館), an old onsen tucked deep in the forest. The water is famously radon-rich and forms a 25-meter limestone dome, one of only two formations of its kind in the world (the other being at Yellowstone), now a registered natural monument of Hokkaido.
For lunch, we stopped at Ishimame Soba in the village of Makkari, on the southern slopes of Mount Yōtei - a small, family-run place ranked among the top 75 soba restaurants in Japan and accessible only by car. Then on to Lake Hangetsu (半月湖), a crater lake at the foot of Mount Yōtei (often called "Ezo Fuji" for its resemblance to the real thing), formed roughly 3,000 years ago by a side eruption.
Otaru - Ceramics, a Polish Connection, and Finally the Nigori Sake
From Lake Hangetsu, we headed to Otaru. This beautifully preserved port town boomed during the Meiji and Taishō eras, then quietly fell out of fashion when the herring industry collapsed, which is exactly why all the old buildings are still standing.
Otaru also gave me the moment I'd been chasing since the start of the trip: finally finding nigori sake. I'd been turned away from some izakayas in Hakodate, and it took until a quiet evening at a small Otaru bar to finally get a glass of it.
Yoichi - Whisky and History
From Otaru, we took a short train ride to the Nikka Whisky Yoichi Distillery. The short version of the story: Masataka Taketsuru, son of a Hiroshima sake-brewing family, traveled alone to Scotland in 1918 to learn whisky-making. He studied chemistry at Glasgow, worked at three Scottish distilleries, married a Scottish woman named Rita Cowan in 1920 against the wishes of both their families, and brought her back to Japan. After working at what would become Suntory, he founded his own distillery in Yoichi in 1934 - chosen specifically for how closely it resembled Scotland: cold winters, peat, sea air, mountain water.
Walking through Yoichi today, you can feel that story in every building. The pagoda-roofed kiln towers, the pot stills heated directly by coal fire (one of the few major distilleries in the world still doing this), and ten buildings now designated Important Cultural Properties of Japan.
A Detour to Sapporo
Our route did not include Sapporo, but circumstances led us to make a quick detour into the city. I had about 45 minutes there - just enough to grab some Japanese green tea and a Pokémon toy for my son. Sapporo looked beautiful and was worth a proper visit some other time. It's only 40 minutes from Otaru, much closer than I'd realized.
Lake Shikotsu
For the final leg, we drove on to Lake Shikotsu (支笏湖) and the historic Marukoma Onsen Ryokan (丸駒温泉旅館), founded in 1915, where we stayed for the night.
Marukoma has one of the most unusual onsens in Japan: among its several pools, there is one outdoor bath whose water level rises and falls with the lake, as it is naturally connected to it. Unfortunately, the lake level was too low during our stay, so this particular pool was out of use - but the other pools were just as relaxing. We went in twice, once in the late afternoon and again at 4:30 am the next morning, my last day in Japan, to catch the sunrise over the lake and the surrounding mountains. Worth every minute of lost sleep.
Lake Shikotsu itself is the second-deepest lake in Japan (363 m), one of the clearest in the world (visibility around 20 meters), and so deep and warm that it never freezes, even in Hokkaido winters.
A Final Day in Narita
After Hasumi-san dropped me off at New Chitose Airport, I flew down to Narita in the morning, where I had about eight hours before my Tokyo-Warsaw flight. I had originally planned to treat Narita as an airport with a hotel and was bracing myself for a boring last day. I could not have been more wrong.
The town itself is a 1080-year-old pilgrimage center built around Naritasan Shinshōji, one of the top three pilgrimage temples in the country (about 5.5 million visitors a year), with a beautifully preserved Edo-period shopping street leading up to it. You can eat unagi from restaurants that have been preparing it the same way for over 300 years.
I had unagi-don for lunch, then bought local sake at Choumeisen (長命泉), a small brewery on Omotesando. I'd hoped to bring back a bottle of nigori. Still, the owner gently warned me that her unpasteurized nigori would ferment in my luggage and possibly explode mid-flight - a wonderful, very Japanese moment of someone protecting me from myself. I bought a pasteurized junmai instead.
I also attended the Goma Fire Ritual at Daihondō, the temple's main hall. Five times a day, every day, for over 1,000 years without interruption, monks light a sacred fire while chanting Shingon Buddhist mantras, accompanied by drums and bells. The flames rise meters into the air. Worshippers can hand over personal items to be blessed in the smoke.
If you ever have an eight-hour layover at Narita, do yourself a favor and skip the airport lounge. Go to Naritasan instead.
Why RubyKaigi Matters
Looking back at RubyKaigi 2026, I again notice that the talks, while excellent, are not what make this conference unique. The talks will be on YouTube. What you can't replicate is the connections, the conversations, the post-conference trips.
A few things I keep thinking about:
The Japanese and Western Ruby scenes are still too separated. Work and products evolve in parallel, with both sides reinventing each other's wheels because we don't talk enough. RubyKaigi pushes against this every year, but three days isn't enough. Honestly, this should be five.
The hospitality of Japanese Rubyists is on another level. Hasumi-san planned a multi-day trip to show me parts of Hokkaido I'd never have found on my own; Japanese attendees patiently practicing English with foreigners at every drink-up; sponsors going out of their way to organize creative events. I don't know any other tech community that operates like this.
The post-conference time matters. People treat RubyKaigi as part vacation, part professional development, and that combination of sightseeing and serious technical conversation is what makes it different from any other conference I've attended. The "official" three days are a fraction of the real experience.
Summary and Final Thoughts
Reflecting on RubyKaigi 2026: the technical content was great, the social events were unmatched, and the post-conference trip across Hokkaido turned this into something far beyond a conference. None of that last part would have happened without Hasumi-san - thank you, once again, for being an extraordinary friend and host.
RubyKaigi 2027 will be in Miyazaki. I'm already looking forward to it. If you've never been to a RubyKaigi, start planning now.