
February 18, 2026
Based on a talk from Kaigi on Rails 2025 by Hayato Okumoto (TwoGate CTO)
Because life is too short to watch bundle exec rspec scroll by like the credits of an extended director’s cut.
⏱️ The Universal Pain: Waiting for CI
Every Rails developer eventually reaches enlightenment — not through meditation, but through staring at a CI pipeline stuck at “Running tests…” for half an hour.
At TwoGate, this wasn’t just annoying — it was operationally dangerous. Their products run at live events, where bugs aren’t theoretical; they’re surrounded by sweaty humans holding smartphones and expectations.
Fast feedback wasn’t a luxury. It was hydration.
🧪 The System Under Test

The case study project:
- Ruby 3.3 / Rails 7.1 (+ Sorbet)
- PostgreSQL + Redis
- ~19k lines of code
- ~58k lines of tests
- ~1,981 RSpec examples
- Initial runtime: 29m 38s
Code-to-test ratio ≈ 1 : 3.1 — proof that tests breed faster than rabbits when left unattended. 2025.09_Kaigi_on_Rails_2025_-_2…
🚀 Step 1: Parallel Tests — “Use All the CPUs You Paid For”

Running tests sequentially on a multi-core machine is like buying an 8-burner stove to boil a single egg.
Using parallel_tests, they split execution across cores.
But there’s a catch: databases don’t like being cloned like suspicious sci-fi characters. Each process needs its own logical DB (via TEST_ENV_NUMBER).
Even then, performance gains were… underwhelming:
29m → 23m
Turns out CPUs weren’t the villain.
⚖️ Step 2: Balance the Load (Not All Tests Are Equal)
Some specs sprint. Others go on spiritual journeys.
If you divide tests evenly by file count, one worker finishes early while another is still compiling the meaning of existence.
Solution: Knapsack Pro
It distributes tests based on historical runtime, not file count.
Think of it as Tetris for specs — but instead of clearing lines, you clear your afternoon.
💿 Step 3: The Real Enemy — Disk I/O

Here’s the twist: parallelism increased database writes, which slammed into the storage ceiling.
Default AWS gp3 volume:
3,000 IOPS
With 8 parallel workers, the database started writing like a caffeinated novelist — and the disk simply couldn’t keep up. 2025.09_Kaigi_on_Rails_2025_-_2…
CPU idle. Disk crying. Developers confused.
Classic bottleneck whodunit.
🧠 Step 4: Put the Database in RAM (Yes, Really)
Enter tmpfs — a filesystem backed by memory.
Mount PostgreSQL’s data directory in RAM:
--tmpfs=/var/lib/postgresql
In GitLab Runner:
[runners.docker.services_tmpfs]"/var/lib/postgresql/data" = "rw,noexec"
Effectively, your test database becomes a mayfly:
- Lives fast
- Dies at reboot
- Leaves no logs
But it is gloriously fast.
⚡ Result: Massive Speedup
With parallelism + RAM disk:
29m → 5 minutes
A 6× improvement just by moving bits from spinning rust (or cloud-simulated rust) into memory. 2025.09_Kaigi_on_Rails_2025_-_2…
At this point, your CI stops being a coffee break and becomes a polite sip.
🧨 Step 5: The Nuclear Option — Physical Hardware
Then came the spicy take.
Instead of scaling cloud instances further, they moved CI to a dedicated machine:
- Ryzen 9
- 32 cores
- NVMe SSD
- 64 GB RAM
- 32 parallel workers
Final runtime:
1 minute 59 seconds
From ~30 minutes to ~2 minutes — a 15× improvement. 2025.09_Kaigi_on_Rails_2025_-_2…
Your CI pipeline now finishes before you can complain about it.
💰 Bonus Round: Cost Efficiency
Cloud equivalent (large EC2 instance):
≈ $1,300/month
Physical machine amortized:
≈ dramatically cheaper
In other words: sometimes the cloud isn’t lighter — just fluffier.
🧩 Why This Matters
Fast CI isn’t just developer comfort. It changes team behavior:
- Smaller commits
- Faster bug detection
- More frequent releases
- Less context switching
- Fewer existential crises
Or put differently:
Slow CI encourages procrastination. Fast CI enables progress.
🏁 Key Takeaways
If you want to speed-run your Rails CI:
- Parallelize tests
- Balance workloads intelligently
- Remove storage bottlenecks
- Consider RAM-backed databases for CI
- Don’t blindly assume cloud = optimal
🧘 Final Thought
Rails has a reputation for being “slow.”
But most of the time, Rails isn’t slow — your infrastructure is just stuck in traffic.
Optimize the road, not the car.
And if all else fails, remember:
The fastest test suite is the one that already passed.
(Second fastest: the one running on tmpfs.)
