← Back to Main Page
Why Go Feels Like a Rocket and Ruby Feels Like a Cozy Couch - Article by Deepan Kumar

Why Go Feels Like a Rocket and Ruby Feels Like a Cozy Couch

Go vs Ruby

I’ve been coding in Ruby long enough to know one truth: Ruby is joyful, expressive, and just feels like home. But every now and then, someone waves a Go benchmark in my face and I can’t help but wonder… why is Go so much faster?

So I went digging. What I found took me from goroutines to Ruby’s GIL to JRuby and TruffleRuby. Buckle up, because this ride is part science, part philosophy, and part therapy for Ruby developers.

Go: The Overachiever

Go is like that student who finishes the exam in 10 minutes and still gets full marks. It’s compiled, so it talks to the machine directly without an interpreter whispering in its ear.

Then it has goroutines. Think of them as mini threads that are so lightweight you can spin up thousands without the CPU breaking a sweat. Go’s runtime scheduler then plays Tetris with these goroutines, packing them efficiently onto actual CPU cores.

Result? Concurrency feels effortless and performance stays sharp.

Ruby: The Poet with a Lock

Ruby, on the other hand, is more like a poet. It doesn’t rush. It wants every line of code to read like a sentence. The downside? Ruby MRI has a Global Interpreter Lock. Imagine a poetry slam where only one poet can speak at a time, even though the stage has four microphones. That’s Ruby threads.

Yes, Ruby threads are real OS threads. But the GIL makes them take turns like kids waiting for the swing. This keeps memory safe but kills true parallel execution for CPU-heavy tasks.

Can’t We Just Remove the GIL?

In theory, yes. In practice, that’s like removing the brakes from a car. Technically faster, but now you’re doomed at the first turn. Without the GIL, every Ruby object would need its own locks and guards. The language would get messy and possibly slower overall.

Go never had this problem because it was built for concurrency from day one. Ruby wasn’t. Ruby was built for happiness, not race conditions.

Enter JRuby and TruffleRuby

Not all Ruby interpreters are created equal. JRuby runs on the JVM, which means it can use real parallel threads and borrow decades of Java optimizations. TruffleRuby runs on GraalVM and takes performance seriously. It skips the GIL, uses JIT compilation, and after a warmup period can sometimes outrun MRI by miles.

But here’s the catch: not every gem plays nice with these alternative Rubies. Especially gems with C extensions. And web servers that boot fast might not benefit from the “wait for warmup” model.

So Where Does Ruby Shine?

Ruby doesn’t need to beat Go at its own game. Ruby shines at making developers happy. Rails still gets apps to production faster than almost anything else. Most web apps are I/O bound, waiting on databases and APIs, not CPU math. And when you need raw speed for things like embeddings, vector search, or machine learning, you can always let Go or Rust do the heavy lifting while Ruby orchestrates.

Think of Ruby as the chef who designs the menu, takes the orders, and keeps everyone smiling. Go and Rust? They’re the ones in the back kitchen, chopping onions at lightning speed.

The Takeaway

Go feels like a rocket. Ruby feels like a cozy couch. One gets you places fast, the other makes the journey enjoyable. Instead of trying to make Ruby into Go, maybe the real win is letting each do what it does best.

And hey, sometimes after a long day of rockets and goroutines, there’s nothing better than sinking into Ruby’s cozy couch.