Case study · Stack

How GitLab runs a giant Rails monolith in the open

GitLab is an open-core platform that covers source control, CI/CD and security in one app, and GitLab.com is the largest install of it. The stack is a deliberately boring Ruby on Rails monolith with PostgreSQL, Redis and Sidekiq, plus Go services for the hot paths, running on Google Cloud and Kubernetes.
Copy this stackgitlab.com DevSecOps platform for code, CI/CD and security · United States · founded 2011

Language

UI library

  • Vue.jsdocs.gitlab.com

    Interactive parts of the UI, mounted into Rails HAML pages.

Hosting

  • Google Cloudabout.gitlab.com

    Cloud where GitLab.com has run since its 2018 move from Azure.

    Why: Azure was not giving GitLab.com the reliability it needed, and Google Cloud offered better performance and consistency, Kubernetes and price.

  • Kubernetesabout.gitlab.com

    Runs GitLab.com's stateless services on Google Kubernetes Engine using the official Helm chart.

    Why: The VM setup was slow to scale and deploy, and Kubernetes promised better scaling, deploys and use of compute.

Database

Login

Data fetching

  • Redisdocs.gitlab.com

    Holds sessions, temporary cache and background job queues.

  • Sidekiqdocs.gitlab.com

    Processes background jobs pulled from the Redis queue.

    Why: Background jobs keep the request and response cycle fast.

  • GraphQLdocs.gitlab.com

    Default API for front-end data, consumed through Apollo.

Backend framework

  • Ruby on Railsabout.gitlab.com

    Framework of the core GitLab monolith.

    Why: Its gem ecosystem and strong conventions help a huge, open codebase stay consistent and easy for newcomers to navigate.

  • Goabout.gitlab.com

    Language of Gitaly, the service that handles every Git call, and other performance-critical paths.

    Why: Ruby is optimized for the developer, not for production, so hot and I/O-bound paths were rewritten in Go.

  • Pumadocs.gitlab.com

    Application server that runs the Rails app for web pages and the API.

File storage

  • Google Cloud Storageabout.gitlab.com

    Object storage for CI artifacts, job logs, uploads and LFS files.

Search

Error monitoring

How they built it

Rails on purpose, with boring solutions

Co-founder Dmitriy Zaporozhets picked Rails even though he mostly wrote PHP at the time, partly because GitHub was built on it. CEO Sid Sijbrandij later defended the choice: the gem ecosystem gives the team great shoulders to stand on, and Rails conventions tell everyone where code belongs.

That last point matters for GitLab's mission that everyone can contribute. A newcomer can find their way around a huge codebase because it follows the Rails happy path, and the team prefers boring solutions over clever tricks.

Sources:about.gitlab.com

Go where Ruby gets slow

Sijbrandij put it bluntly: Ruby was optimized for the developer, not for running in production. So the code paths hit most often, or the ones that spend their time waiting on disk and network, were rewritten in Go.

The biggest result is Gitaly, a Go service that handles every Git call GitLab makes. It was built to remove the need for NFS for Git storage, and its stated goal is fault-tolerant horizontal scaling of Git storage, especially on GitLab.com. Today all application code reaches repositories through it.

Sources:about.gitlab.com gitlab.com docs.gitlab.com

From Azure to Google Cloud in 2018

GitLab.com used to run on Azure, and it was not ready for mission-critical work. In 2018 the team moved it to Google Cloud, citing the performance and consistency they needed, plus Kubernetes and price. They used GitLab's own Geo replication to copy the data and moved about 200 TB of CI artifacts, uploads and LFS objects into Google Cloud Storage.

The numbers improved quickly. Availability went from 99.61% before the move to 99.93% by April 2019, and daily errors dropped from an average of 8.2 to about one.

Sources:about.gitlab.com

Moving to Kubernetes, one service at a time

The VM-based setup was slow to scale and deploy, so in August 2019 GitLab.com started moving to Google Kubernetes Engine, beginning with the Container Registry. Web, API, Git traffic and Sidekiq jobs followed, all running from the same official Helm chart customers use.

The stateful parts stayed on VMs: PostgreSQL, Redis, GitLab Pages and Gitaly. A year in, the team reported much faster and safer deploys, though cross-zone network traffic became a new cost to watch.

Sources:about.gitlab.com

Vue islands on HAML pages

The front end is a mix: Rails renders HAML pages, and Vue.js apps are mounted into them where the page needs interactivity. The frontend guide asks teams to keep the number of Vue apps per page low.

For data, GraphQL with Apollo is the default, and REST stays for simple HAML pages and older code. Vuex is deprecated in favor of Pinia or plain stateful components.

Sources:docs.gitlab.com

Also detected on their website

Found on the homepage with the open Wappalyzer rules (HTML, scripts and headers). It shows what runs in the browser, not the whole backend.

  • Cloudflare
  • Dreamdata
  • GitLab
  • HSTS
  • HTTP/3
  • Marketo
  • Nuxt.js
  • OneTrust
  • Optimizely