Best VPS for GitLab Self-Managed: When a Small Team Should Leave GitHub SaaS
If your team has been growing on GitHub SaaS, you’ve probably hit at least one wall, a CI minute cap, a storage limit, or a compliance checkbox that suddenly matters. That’s exactly when the idea of the best VPS for GitLab self-managed starts making real sense.
This article is not just a setup guide; it’s a decision guide. You will discover the reasons to move, the real cost, what your VPS can handle, and when a dedicated server becomes necessary.
Table of Contents
Why Small Teams Reconsider GitHub SaaS
GitHub SaaS is great for getting started because it is easy, fast, and the free tier gives you 2,000 CI/CD minutes per month. For most single developers or very small teams, that’s enough. But the moment your team ships code every day, those minutes disappear fast.
GitHub Team costs $4 per user per month, which sounds low. But as soon as you add more CI usage, costs stack up quickly. GitHub’s free plan only includes 500 MB of artifact storage, and anything beyond your included quota gets billed separately. For a team of 10 actively deploying projects, this adds up month after month.
Beyond cost, GitHub is a fully managed SaaS. You can’t control where your data lives, how long logs are stored, who has access at the infrastructure level, or how your container images are handled. For teams under compliance requirements such as healthcare, finance, and government contractors, this is a hard stop. That’s why many teams start seriously researching the best VPS for GitLab self-managed as a real alternative.
What GitLab Self-Managed Gives You
GitLab Community Edition (CE) is fully open source and free to use. When you self-host it, you get the full DevOps lifecycle in a single application, including version control, CI/CD pipelines, issue tracking, merge requests, a built-in container registry, and more, all without paying per user.
Here’s what you own when you run GitLab self-managed:
- Your data: Repos, issues, pipelines, and artifacts are stored on hardware you control.
- Unlimited CI minutes: Limited only by your server’s CPU, not a billing clock.
- Built-in container registry: No need for Docker Hub or a third-party registry.
- Full SMTP email control: Configure your own mail server or any SMTP provider.
- Backup control: You define the schedule, retention, and storage destination.
- Compliance-ready: Restrict access at the network level, enforce 2FA, and keep audit logs.
Also, GitLab supports the entire DevOps lifecycle natively, including Kubernetes integration and Terraform state management, things that GitHub requires external tools for.
Cost Comparison Between GitHub Team and GitLab Self-Managed
Here is what you actually pay over a year for a 10-person team in GitHub and self-managed GitLab:
| Item | GitHub Team | Self-managed GitLab |
|---|---|---|
| Per user/month | $4 | $0 (CE is free) |
| Annual for 10 users | ~$480 | $0 |
| CI minutes included | 3,000/month | Unlimited (your server) |
| Extra CI minutes | $0.008/minute | $0 |
| Container registry | Limited storage | Included, self-managed |
| VPS cost (example) | $0 | ~$20–$60/month |
A powerful VPS for a team of 5 to 15 people runs between $20 and $60 per month, depending on specs. Even at $60 per month, that’s $720 per year, which is close to what GitHub Team charges for 10 people in base cost alone, before CI overages. Once your pipelines are active, GitLab self-managed becomes the cheaper option within the first few months.
Choosing the best VPS for GitLab self-managed quickly becomes the more affordable path once you face CI overages and pricing on GitHub.
What Your VPS Needs to Run GitLab
GitLab is not lightweight; it runs multiple services simultaneously, including Puma, Sidekiq, PostgreSQL, Redis, Gitaly, and Nginx. All of these run on the same machine if you use a single-node setup.
According to the official GitLab documentation, here are the minimum and recommended specs:
| Spec | Minimum | Recommended |
|---|---|---|
| vCPU | 2 | 4 |
| RAM | 4 to 8 GB | 8 to 16 GB |
| Storage | 40 to 60 GB SSD | 100 GB+ SSD |
The Linux package alone needs about 2.5 GB of storage space for installation, and with PostgreSQL, logs, and OS overhead, you should plan for at least 40 GB of disk space before any repository data. SSD is strongly recommended because GitLab’s performance depends heavily on disk I/O.
For teams up to 1,000 users or 20 requests per second, GitLab recommends 8 vCPU and 16 GB of RAM. For a small team of 5 to 15 developers, a 4 vCPU and 8 GB RAM VPS is a good option that gives you space to grow.
You can start with a fast NVMe Linux VPS, which lets you choose your specs and scale up as your team and repositories grow.
Understanding CI Runner Load
One of the biggest surprises for teams new to self-managed GitLab is the CI runner load. By default, if you install a GitLab Runner on the same VPS as GitLab, every CI job competes directly with the GitLab web server and database for CPU and RAM. This means a busy pipeline can make your GitLab UI slow or unresponsive.
This is a key factor when evaluating the best VPS for GitLab self-managed for your team.
GitLab’s system requirements for runners depend entirely on anticipated job concurrency and complexity. The general rule:
- Light CI, tests only, and 2 to 3 concurrent jobs: A 4 vCPU and 8 GB VPS can handle GitLab and a runner together.
- Active CI, Docker builds, and multiple concurrent pipelines: Separate the runner onto a second VPS.
- Heavy CI, multi-stage Docker builds, parallel testing, and container image publishing: Move runners to a dedicated server or a pool of VPS nodes.
The best setup for a growing team is to keep GitLab on one VPS and run your CI runners on a separate and smaller machine. This prevents pipeline load from impacting your developers’ daily Git workflow.
Storage in GitLab Instances
Storage is the fastest-growing factor in any GitLab instance. There are four main storage consumers you need to plan for:
- Git repositories and LFS objects: Grow with every commit, branch, and large file.
- CI job artifacts and pipeline logs: Can grow very fast if artifact expiry is not configured.
- Container registry images: Docker images are large, usually 200 MB to 2 GB each.
- Backups stored locally: If you keep backups on the same disk, they double your storage needs.
It is recommended to start with more storage than you think you need and monitor it regularly. When disk usage consistently exceeds 70%, it’s time to expand before it becomes an issue. Most VPS providers let you add storage volumes without rebuilding the server.
Also, you can set CI artifact expiry rules in your .gitlab-ci.yml files using the expire_in directive. For example, expire_in: 1 week prevents old build artifacts from filling your disk over time. For container images, set up a cleanup policy in your registry settings to remove old and unused tags automatically.
Email and SMTP in GitLab
GitLab sends emails for many things, including merge request notifications, CI status, user invitations, password resets, and security alerts. Without a working SMTP setup, your team will miss these notifications, and user registration will be broken.
GitLab self-managed supports any standard SMTP provider through /etc/gitlab/gitlab.rb. You can use:
- Gmail or Google Workspace, which is common for small teams.
- AWS SES, which is cost-effective for higher volume.
- Mailgun, Postmark, or SendGrid are developer-friendly options.
- Your own mail server for full control.
The configuration is straightforward:
gitlab_rails['smtp_enable'] = true
gitlab_rails['smtp_address'] = "smtp.gmail.com"
gitlab_rails['smtp_port'] = 587
gitlab_rails['smtp_user_name'] = "yo**@***il.com"
gitlab_rails['smtp_password'] = "your_app_password"
gitlab_rails['smtp_domain'] = "gmail.com"
gitlab_rails['smtp_authentication'] = "login"
gitlab_rails['smtp_enable_starttls_auto'] = true
gitlab_rails['gitlab_email_from'] = 'gi****@********in.com'
After adding this to gitlab.rb, run sudo gitlab-ctl reconfigure to apply the changes. Test the email setup from the GitLab admin panel under Admin > System Hooks or by sending a test email from Admin > Email.
Built-in Container Registry in GitLab
One of GitLab’s best advantages over GitHub for self-hosted teams is the built-in container registry. You get a private Docker registry at no additional cost, running on your own infrastructure. Your CI pipelines can push and pull images directly without leaving your server.
This is another reason the best VPS for GitLab self-managed is a practical choice for teams that rely heavily on Docker-based workflows.
To enable the registry, set the registry URL in gitlab.rb:
registry_external_url 'https://registry.yourdomain.com'
Then, run sudo gitlab-ctl reconfigure. GitLab handles the registry’s authentication through its own token system; your developers log in with their GitLab credentials.
Keep in mind that container images take up storage. A single Node.js Docker image can be 300 to 800 MB, and production-grade images can be larger. You must set up a registry cleanup policy to automatically remove old and untagged images. You can find this setting per project under:
Settings > Packages & Registries > Container Registry.
Backup Strategy for Self-Managed GitLab
GitLab provides a built-in backup command that captures repositories, the database, CI artifacts, uploads, wikis, and more.
You can run a manual backup like this:
sudo gitlab-backup create
This creates a compressed archive in /var/opt/gitlab/backups/. But two important files are not included in this backup and must be saved separately:
/etc/gitlab/gitlab.rb: Your configuration file/etc/gitlab/gitlab-secrets.json: Encryption keys for tokens and credentials
Without these two files, a backup archive is not restorable. You must always back them up alongside the main backup.
Automate daily backups with a cron job:
# Daily backup at 2 AM
0 2 * * * /usr/bin/gitlab-backup create CRON=1
# Weekly config backup
0 3 * * 0 cp /etc/gitlab/gitlab.rb /var/opt/gitlab/backups/config/ && \
cp /etc/gitlab/gitlab-secrets.json /var/opt/gitlab/backups/config/
Never store backups only on the same VPS; if the disk fails, you lose both GitLab and the backups. Send them to an S3-compatible object store, another server, or a remote location.
VPS vs. Dedicated Server for GitLab Self-Managed: When to Make the Move
A VPS is the right option to start for most small teams. It’s easy to provision, affordable, and scalable enough for the early stages, but as usage grows, a VPS has real limits.
A VPS shares physical hardware with other tenants. Under heavy load, especially during large Docker builds or parallel CI runs, you can hit I/O contention and CPU throttling that a dedicated server would not have.
When your VPS’s RAM, CPU, storage, or bandwidth consistently exceeds 70% utilization, it’s time to consider moving.
Here’s a clear breakdown of which scenario fits which infrastructure:
| Situation | VPS Sufficient | Need Dedicated Server |
|---|---|---|
| Team Size | 5 to 20 developers | 20+ active developers |
| CI Jobs | Low to medium concurrency | Heavy parallel pipelines |
| Docker Builds | Occasional | Daily, multi-stage builds |
| Container Registry | Small number of images | Large registry with many projects |
| Storage | Under 200 GB total | 500 GB+ and growing |
| Uptime Requirement | Standard (99.5%) | High availability (99.9%+) |
| Compliance | Basic | Strict |
When you need a dedicated server, PerLod’s dedicated servers with NVMe storage give you bare-metal performance without the overhead of shared virtualization.
The migration path from VPS to dedicated server is also straightforward using GitLab’s built-in backup and restore process. You create a full backup on the old server, provision the new dedicated server, install GitLab, restore the backup, update DNS, and your team is back online with zero data loss.
Choosing the Best VPS for GitLab Self-Managed by Team Size
Based on official GitLab requirements and practical deployment experience, here are the recommended VPS configurations by team size:
| Team Size | vCPU | RAM | Storage | Notes |
|---|---|---|---|---|
| 1 to 5 developers | 2 | 8 | 60 GB SSD | Minimum viable; no heavy CI |
| 5 to 15 developers | 4 | 8 to 16 GB | 100 to 200 GB SSD | Recommended starting point |
| 15 to 30 developers | 8 | 16 GB | 200 to 500 GB SSD | Separate runners recommended |
| 30+ developers | Consider dedicated | 32+ BG | 500 GB+ | Dedicated server or HA setup |
Always use SSDs; older hard drives and network storage will seriously slow down your Git and CI performance. Also, if you run Docker-in-Docker for your builds, add extra RAM. Every build container eats up memory on top of what GitLab already uses.
Security Basics You Should Not Skip for GitLab Self-managed
Here is a simple security checklist that you should not forget:
- Enable HTTPS with a Let’s Encrypt certificate via GitLab’s built-in
letsencrypt['enable'] = truesetting. - Enforce two-factor authentication (2FA) for all users from Admin > Settings > General > Sign-in restrictions.
- Disable root SSH login on the VPS and use a dedicated sudo user with SSH key authentication.
- Limit open ports to 22 (SSH), 80 (HTTP for Let’s Encrypt), and 443 (HTTPS).
- Keep GitLab updated; GitLab releases regular security patches, and staying current is the most effective protection.
- Enable audit logs to track logins, access changes, and security events.
For teams in regulated industries, running the best VPS for GitLab self-managed also gives you more network control. You can place it behind a VPN or firewall, so only team members on a trusted network can access the web interface.
Conclusion
Moving from GitHub to the best VPS for GitLab self-managed is the best way to secure your data and stop paying per-minute CI costs. You can start with a PerLod Linux VPS, 4 vCPU, 8 to 16 GB RAM, and 100 GB+ SSD for predictable pricing and unlimited CI minutes. Once your team needs bare-metal performance, you can upgrade to dedicated hardware.
Make the switch before your SaaS bills become a real problem. We hope you enjoy this guide.
FAQs
Is GitLab Community Edition free?
Yes. GitLab CE is fully open source and free to use with no user limits. You only pay for the server you run it on.
Can I migrate from GitHub to GitLab self-managed?
Yes. GitLab has built-in GitHub import tools that migrate repositories, issues, pull requests, labels, and milestones. The import runs directly from the GitLab UI.
Is the GitLab container registry good enough for production use?
Yes. The built-in container registry is production-ready and integrates directly with CI pipelines. Just make sure you configure a cleanup policy to prevent old images from filling your storage.