Virtualization

Self-hosted GitLab CE: minimum viable server spec

I have seen GitLab CE grind a 2 GB VPS to a halt, and I have also seen it run reasonably well on hardware that most guides dismiss as "too small." The difference is knowing exactly which knobs to turn and what to expect before you hand over your credit card. This article lays out the real, honest minimum server requirements to run GitLab CE, not the marketing version, and matches each spec to a concrete VPS plan that will not leave you staring at a 502 error page every time three people push code.

Prerequisites

  • A Linux VPS running Ubuntu 24.04 LTS or Debian 12. I recommend Debian 12 because its lower default memory footprint leaves more room for GitLab.
  • Full root access via SSH. GitLab needs to bind to privileged ports (80, 443) and install system packages.
  • A registered domain name pointed at your VPS IP address (an A record). GitLab does not run comfortably on a raw IP.
  • Familiarity with the terminal. This is not a shared hosting setup.

自托管 GitLab CE 至少需要 4 GB 内存和 2 个 vCPU,否则服务会频繁崩溃。

Self-hosted GitLab CE needs at least 4 GB of RAM and 2 vCPUs, or the service will crash frequently.

Why Self-Host GitLab at All?

GitLab SaaS is a mature product, but there are concrete reasons to run your own instance. When you self-host, every pipeline minute, every artifact, every container registry push stays inside your own infrastructure. No per-user seat licensing, no storage limits that grow into surprise bills, and no "maintenance window" that interrupts your deployment schedule at an inconvenient hour. For teams that handle sensitive code or operate under data-residency rules, for example, a Vietnamese company whose code must stay on infrastructure operated by Viettel IDC or VNPT IDC under domestic jurisdiction, self-hosting is not a luxury. It is a compliance requirement. The trade-off is that you become the operations team, which means the server spec matters.

What GitLab CE Actually Needs Before It Works

GitLab is a monolith. Inside the same /opt/gitlab directory sit a Rails application server, Sidekiq background workers, a PostgreSQL database, a Redis cache, an Nginx reverse proxy, and a repository file system that grows as your team commits. Each one of these components demands a slice of your RAM and CPU, and the official documentation is surprisingly honest about the floor: 4 GB of RAM and 2 vCPUs for a basic installation with up to 100 users. That is not a "nice to have." That is the limit below which the gitlab-ctl reconfigure command completes, but the web UI times out, Sidekiq queues back up, and the bundled Prometheus process gets OOM-killed every few hours.

I have tested GitLab CE 16.x and 17.x on a single vCPU with 2 GB of RAM. It installs. It runs. Then the first push from two developers at the same time triggers a CI pipeline, Prometheus scrapes metrics, and the server starts swapping heavily. The swap file is on NVMe storage, so it is not as painful as spinning rust, but it is still orders of magnitude slower than RAM. The experience is borderline usable for one person testing the interface; it is not usable for a team.

ComponentMinimum RAM (dedicated, no other apps)Notes
GitLab Rails + Puma1.5 to 2 GBHandles HTTP requests and API calls
PostgreSQL512 MB, 1 GBDatabase shared_buffers + work_mem
Redis128 MBMostly negligible
Sidekiq512 MB, 1 GBBackground jobs, CI pipeline orchestration
Prometheus + exporters300 to 500 MBMonitoring stack bundled by default
OS + overhead500 MB, 1 GBDebian 12 is lighter than Ubuntu here
Total realistic minimum4 GB2 vCPU floor, 8 GB recommended for comfort

Step 1, Choosing the Right VPS Tier for GitLab CE

Given the numbers above, the sweet spot is a 4 GB RAM VPS with 2 vCPUs. At thueVPS, that is the VNx2 tier: 2 vCPU, 4 GB RAM, 50 GB NVMe storage, a dedicated IPv4 from the Vietnam range, and domestic bandwidth capped at 100 Mbps on a 1 Gbps port. The international bandwidth is a shared pool, roughly 4 to 10 Mbps, which is fine for pulling Docker images from Docker Hub or for a small remote team. Keep in mind that traffic is unlimited with no data cap, so you are not counting gigabytes.

The VNLite tier (1 vCPU, 2 GB RAM, 20 GB NVMe) is tempting because it is cheaper, but I do not recommend it for GitLab. A 2 GB machine will work only if you disable Prometheus, reduce Sidekiq concurrency to one, and never run more than one CI job at a time. Even then, the experience is fragile. If your team is larger than two people, skip it and start at VNx2. For teams of 10 to 20 developers running multiple CI pipelines, the VNx4 (4 vCPU, 8 GB RAM, 80 GB NVMe) gives you room to breathe, especially if you store large artifacts or container images in the built-in registry. The VNx8 (8 vCPU, 16 GB RAM, 100 GB NVMe) is overkill for most GitLab-only workloads; you would use it if you also run additional services on the same host, but the standard recommendation for a dedicated GitLab instance is to keep other services off it.

Step 2, Installing GitLab CE on Ubuntu 24.04 or Debian 12

The installation process has not changed much in recent years. Open an SSH session as root and run the following commands. I use Debian 12 in the example, but the procedure on Ubuntu 24.04 is identical except for the package repository URL (you select the distribution name accordingly).

apt update
apt install -y curl openssh-server ca-certificates perl

Then add the official GitLab repository and install the CE package:

curl -sS https://packages.gitlab.com/install/repositories/gitlab/gitlab-ce/script.deb.sh | bash
EXTERNAL_URL="https://gitlab.yourdomain.com" apt install gitlab-ce

Replace gitlab.yourdomain.com with your real domain. The installer runs gitlab-ctl reconfigure at the end, which sets up PostgreSQL, Redis, Nginx, and all internal services. This step takes 3 to 5 minutes on a 4 GB VPS with NVMe storage. When it finishes, you can access the GitLab web UI at https://gitlab.yourdomain.com and set the initial root password from the page that loads.

Step 3, Post-Install Tweaks That Save Your Sanity

The default configuration is designed for servers with more resources than a 4 GB VPS. You need to make a few changes immediately.

Disable Prometheus and node_exporter, the bundled monitoring stack consumes about 400 MB of RAM on its own. Unless you are integrating GitLab metrics into a central Prometheus setup, turn it off:

gitlab-ctl stop prometheus
gitlab-ctl stop node_exporter
gitlab-ctl stop redis_exporter
gitlab-ctl stop postgres_exporter
gitlab-ctl stop gitlab_exporter

echo "prometheus_monitoring['enable'] = false" >> /etc/gitlab/gitlab.rb
echo "node_exporter['enable'] = false" >> /etc/gitlab/gitlab.rb

Then run gitlab-ctl reconfigure and gitlab-ctl restart. Check the memory difference with free -h. You should see roughly 300 to 400 MB freed.

Reduce Sidekiq concurrency, the default is 25 Sidekiq threads. On a 4 GB box, that number can spike memory usage during CI backlogs. Set it to 10:

echo "sidekiq['concurrency'] = 10" >> /etc/gitlab/gitlab.rb
gitlab-ctl reconfigure
gitlab-ctl restart

Lower PostgreSQL memory settings, the automatic tuning picks values that assume more RAM is available. Override them to be conservative:

echo "postgresql['shared_buffers'] = '512MB'" >> /etc/gitlab/gitlab.rb
echo "postgresql['work_mem'] = '8MB'" >> /etc/gitlab/gitlab.rb
gitlab-ctl reconfigure
gitlab-ctl restart postgresql

Verify that everything is running and within your memory budget:

gitlab-ctl status
free -h

Each service should show a PID and a run state. The free output should show 500 to 800 MB free + cached, with no swap usage.

Step 4, Setting Up Backups (Do Not Skip)

GitLab stores your code, issues, CI/CD configurations, and merge requests in one PostgreSQL database plus the repository file system on disk. The built-in backup Rake task is reliable and should run daily through a cron job:

gitlab-rake gitlab:backup:create
echo "0 3 * * * /usr/bin/gitlab-rake gitlab:backup:create CRON=1" > /etc/cron.d/gitlab-backup

The backup archive lands in /var/opt/gitlab/backups. Copy it off the server to a separate location, thueVPS offers snapshot-based backups that you can enable from the control panel, which give you a full disk-level image on top of the application-level backup. Using both is the correct approach. Snapshots handle hardware failure; the Rake backup handles accidental project deletion or a corrupt Git repository.

Also back up the /etc/gitlab/gitlab.rb file. Without it, a restore from a Rake backup fails because the configuration is missing. The easiest way is to include it in your regular external file backup routine:

cp /etc/gitlab/gitlab.rb /var/opt/gitlab/backups/

FAQ

Can I run GitLab CE on a 2 GB RAM VPS?

Technically yes, but only for a single user running zero CI pipelines and with Prometheus and Sidekiq reduced to minimal settings. The experience is sluggish and the risk of OOM kills is high. For any team of two or more, 4 GB is the floor.

Is 1 vCPU enough for GitLab CE?

GitLab is multi-threaded and benefits from multiple cores, especially during CI pipeline execution and repository operations. One vCPU works for a solo user doing occasional pushes, but Puma and Sidekiq will contend for the same core, causing request timeouts under load. Two vCPUs are the safe minimum.

How much storage do I need for GitLab CE?

The base installation uses about 2 GB. Your actual storage need depends on your repository sizes and whether you keep CI artifacts and container images. A 50 GB NVMe volume (VNx2) is comfortable for a small team with standard-sized projects. If you commit large binary files or keep many pipeline artifacts, start at 80 GB (VNx4).

Does GitLab CE require a registered domain?

Technically, no. You can install GitLab on a raw IP address using HTTP, but HTTPS will not work without a domain (Let's Encrypt requires a domain to issue certificates). GitLab itself generates absolute URLs from the EXTERNAL_URL parameter, and most operations, clone URLs, CI runner registration, webhook callbacks, produce broken links when the host is an IP. Use a domain.

Can I migrate GitLab data from one VPS to another?

Yes. The built-in Rake backup and restore procedure is designed for migrations. Take a backup on the old server, copy the archive to the new server, install the same GitLab version, run the restore command (gitlab-rake gitlab:backup:restore), and you are done. The entire process takes 10 to 15 minutes for a typical data set.

Can I use a GitLab VPS with a dedicated IPv4 from Vietnam for serving users inside the country?

Yes. The network is domestic with low latency to Vietnamese users because traffic routes through local exchanges (VNPT, Viettel, FPT, CMC Telecom). The dedicated IPv4 is from the Vietnam range, so your Git server resolves and connects with Vietnamese peers at domestic speeds rather than routing through international transit. For a development team located in Vietnam, that matters for clone and push performance.

Related articles

自托管 GitLab CE 的最低服务器配置

GitLab CE 最低要求 4 GB 内存和 2 个 vCPU,2 GB 内存的 VPS 仅适合单人测试。建议开启 NVMe 存储的越南 VPS,并关闭 Prometheus 以节省内存。使用内置备份工具和快照双重保护数据。团队在越南使用时,本地 IPv4 能显著提升推送和克隆速度。

Note: This guide is for general reference. Every system and infrastructure has its own specifics, so test each step in a safe environment and consult a qualified engineer before applying it in production.