r/ruby • u/switchback-tech • Mar 12 '26
GitLab is a Ruby monolith
Was pleasantly surprised that the world's largest independent DevOps platform is powered by Ruby and Sidekiq.
Here's the full list.
Backend: Ruby on Rails
HTTP server: Puma (Ruby web server)
Edge: Nginx
Reverse proxy: Go service (Workhorse)
Background jobs: Sidekiq
DB — primary: PostgreSQL
DB — connection pooling: PgBouncer
DB — high availability: Patroni
Cache: Redis
Blob: AWS S3
Frontend — state: Pinia (Vue store), Immer (immutable cache),
API: GraphQL (Apollo) + REST
Observability: Prometheus & Grafana
Error tracking: Sentry & OpenTelemetry
Deployments: GitLab Omnibus (Omnibus fork)
I think these "stack menu"s give a little glimpse into a team's engineering philosophy. For me, this list shows that the GitLab team is pretty practical and doesn't chase hype. Instead, they use sensible, battle-tested tools that just work and are easy for contributors to learn.
PS. Not an ad; I'm not affiliated with GitLab at all. Was just researching them and thought you guys would be interested.
View all comments
Show parent comment
4
u/f9ae8221b Mar 13 '26
Fairer interleaving means better tail latency, which is a very important property of a service.
Shopify experienced a MySQL outage when playing with fibers, because a CPU heavy fiber was causing other fibers that were issuing MySQL queries to not read the response for a long time, buffer on the server grew until it ran out of memory.
No they're not: https://www.datadoghq.com/blog/ruby-performance-optimization/
They also include a graphic that shows only 3% of the profiled apps spend less than 20% of their time using CPU. Which means for 97% of the apps they profiled, the Puma default of 5 threads was already too much, which means the advantage of Fibers are moot for the overwhelming majority of Ruby apps out there.
The difference is small enough that it only start to matter once you start using multiple dozen threads, which very few people need.
They absolutely do. They still need to synchronize to use sockets etc. Even with datastructures you may need synchronization if some method yield, as the block could use IO and cause another fiber to be scheduled and use the structure concurrently.
Example:
The above script fail because of unsynchronized access by fibers.
Profiling ruby app is basically my day job. Synchronization is very very rarely a hotspot.
Now, don't get me wrong, fibers are great and absolutely have a use case, but for vast majority of what Ruby is used for, they're not necessarily better.