Ruby: GVL deep dive
This course examines the Global VM Lock (GVL) in CRuby, the lock that guards the virtual machine's own state. It covers what the lock protects inside the VM and why your shared data sits outside that list. Lessons show a counter losing increments without a Mutex, explain when the lock is released around I/O, sleep and C extensions, and describe timer preemption and the M:N scheduler. The course closes with measuring wall time against CPU time and applying the results to Puma threads and Ractors in a Rails process.
What you'll learn
- ✓What the GVL protects inside the VM and what it leaves unprotected
- ✓Why a shared counter needs a Mutex even with the GVL
- ✓When the lock is released around blocking I/O, sleep and C extensions
- ✓How timer preemption and the M:N scheduler affect Ruby threads
- ✓How to compare wall time with CPU time to find GVL-bound work
- ✓How to set Puma's thread count and weigh Ractors in a Rails process
The lock and its name
Two engineers are looking at the same graph. Puma runs sixteen threads, the box has eight cores, and CPU sits at 12% while p95 latency climbs. One says "the GIL is the problem". The other says "we aren't even CPU-bound, add threads". Both are arguing about a lock neither of them has ever measured.
Read the full lesson free →Curriculum
7 lessonsThe lock and its name
Names the Global VM Lock, explains why GVL fits better than GIL, and outlines its two release points.
What the lock actually protects
Lists the VM state the GVL protects, including allocation and the garbage collector, and where that guarantee stops.
The GVL does not make you thread-safe
Shows an unsynchronized counter losing three quarters of its increments and fixes it with one Mutex around the whole sequence.
When the lock is released
Explains how blocking I/O, sleep and rb_thread_call_without_gvl release the lock, and why threaded web servers benefit.
Preemption and the switching model
Measures timer preemption near 100 ms, covers Thread.pass, and shows that the M:N scheduler leaves GVL semantics unchanged.
Measuring whether you are GVL-bound
Compares wall time with CPU time to classify a workload and decide whether adding threads helps it.
The GVL in a Rails process
Applies the GVL to Puma's thread count in a Rails app and explains what Ractors change and what they keep.