If you are paying per-seat for a hosted Git platform, the maths changes quickly as your team or repository count grows. A self-managed Git server on a cheap VPS — Gitea or Forgejo — can replace most of that spend for a fixed monthly cost. The question is not whether it is cheaper, but whether it is cheaper for your specific usage and whether you can carry the operational load.
The cost comparison that actually matters
| Setup | Monthly cost | Annual cost | Notes |
|---|---|---|---|
| GitHub Team (5 users) | $20 | $240 | Per-seat, scales linearly |
| GitHub Team (15 users) | $60 | $720 | No CI minutes included in base |
| Budget VPS (2 vCPU/4 GB) | $6–12 | $72–144 | Flat, user count irrelevant |
| Budget VPS + offsite backup | $10–18 | $120–216 | Add storage for repos |
The break-even is stark. Even with backup add-ons, a self-hosted Gitea instance undercuts GitHub Team once you pass about six or seven seats. At fifteen seats the self-hosted option is roughly a fifth of the price.
What you actually give up
Be honest about the trade before you migrate:
- Uptime is yours. A hosted platform has staff on call; your VPS does not.
- CI/CD is separate. Gitea Actions exists but you will run the runners, possibly on another host.
- Backups are mandatory. You are one disk failure from losing every repository.
- You patch it. Gitea and Forgejo release frequently.
For a small team comfortable with a Linux shell, these are routine. For a team with no one to handle them, the hosted fee is buying real operational coverage.
Sizing the instance
| Users / repos | vCPU | RAM | Storage |
|---|---|---|---|
| 1–5 users | 1 | 1–2 GB | 20 GB |
| 5–20 users | 2 | 4 GB | 40–80 GB |
| 20–50 users | 4 | 8 GB | 100 GB+ |
Gitea is famously light: a 1 GB instance runs a small team fine. You can sanity-check specs against current value VPS plans before buying. Repositories are mostly text, so storage pressure comes from LFS assets and CI artefacts, not the code itself.
Installation in outline
The official binary or Docker image gets you running in under an hour:
- Create a non-root user and install a reverse proxy (Caddy or Nginx) with TLS.
- Deploy Gitea or Forgejo via Docker Compose with a bind-mounted data volume.
- Point DNS at the host and enable automatic certificates.
- Register the admin account and disable open sign-ups.
- Configure a scheduled backup of the data volume to offsite storage.
- Optionally mirror repositories to a second location for redundancy.
Backups are non-negotiable
The single biggest mistake self-hosters make is treating their Git server as a backup. It is a primary. Dump the database plus the repositories directory nightly, push the archive to object storage or an offsite host, and test a restore before you rely on it. A restorable backup is the difference between a cost saving and a catastrophe.
When self-hosting is the wrong answer
- You depend on hosted CI/CD minutes and marketplace integrations.
- No one on the team can respond to a 2am outage.
- You need enterprise compliance or SSO guarantees.
- Your team is one or two people and the seat cost is trivial.
For everyone else, the economics favour self-hosting. A small VPS comparison makes the choice concrete: pick a flat-rate plan, budget an equal amount for backups, and you have a private Git server for a fraction of per-seat pricing.
Migration without downtime
Moving off a hosted platform is less risky than it sounds because Git is distributed by nature. Repositories clone with their full history, so the worst case is that you push an existing repo to your new server and lose nothing. Run the migration in parallel rather than as a switchover: stand up Gitea or Forgejo, create the destination repositories, and push every repo from your current remote before changing any developer’s origin. Verify a clone and a fresh commit from a second machine before you cut over.
- Create the destination repos with matching names and visibility.
- Push all branches and tags from the old remote to the new one.
- Test a clone, a commit, and a push from a clean machine.
- Keep the old platform active for a grace period as a fallback.
- Update each developer’s origin URL only after the test passes.
Issues, pull requests, and comments live outside the Git objects and need a separate export and import step, usually via the platform’s API. Budget an hour or two for that if your history matters; for a young repository it is often faster to start the issue tracker fresh.
Hardening the host without a monthly bill
Once the server is live, a handful of free measures keep it dependable. Restrict SSH to key authentication only and disable password logins. Put the Git service behind a TLS-terminating reverse proxy so certificates renew automatically. Enable the host firewall and expose only ports 80 and 443 to the internet, leaving SSH restricted to your own addresses where possible. Turn on unattended security updates for the operating system. None of this costs anything beyond the initial setup, and together they remove the most common ways a self-hosted service is compromised or taken down.
Add resource alerts so you learn about a full disk or a runaway process before it becomes an outage, and keep the backup job under the same monitoring. A self-hosted Git server run this way is boring in the best sense: it just works, and it costs a fixed, predictable amount each month regardless of how many developers you add.
The verdict
Self-managed Gitea or Forgejo on a cheap VPS is one of the clearest cost wins available to a small technical team: flat pricing independent of user count, full control of your data, and a break-even point well below most teams’ headcount. Go in with eyes open about backups and patching, and it pays for itself many times over.

