# Internal Forge Comparison
This repository lists the pros and cons of three popular open-source Git forges (**GitLab CE**, **Gitea**, and **Forgejo**) based on a side-by-side comparison in a self-hosted test lab on a single VPS ([github.com/matteodelucchi/gitforgelab](https://github.com/matteodelucchi/gitforgelab)).
The goal is to provide a practical reference for teams and organizations evaluating which Git forge best fits their needs, based on real-world usage and feature comparisons.
## Why This Exists
Choosing the right Git forge for a team or company is not trivial.
Each platform differs in resource usage, feature set, administration complexity, and SSO integration.
This lab deploys all three behind a shared reverse proxy with centralised OIDC authentication so they can be evaluated under identical conditions (same hardware, same identity provider, same workflow).
The entire infrastructure is defined as code (Terraform + Ansible + Docker Compose) and can be torn down and recreated in minutes.
## Limitations
This is a **test lab**, not a production deployment.
- Runs on a **single VPS**. There is no high-availability, redundancy, or horizontal scaling.
- **SSH Git access is disabled**; repositories are accessed over HTTPS only.
- All services share **one PostgreSQL and one Redis** instance to save resources.
- GitLab is **memory-tuned aggressively** (2 Puma workers, 5 Sidekiq concurrency) and will be slow under real workloads.
- No backup strategy is included.
# Comparison
## Quick decision guide
| If we want… | Choose |
| -------------------------------------------------------------------------------------------------------------------------- | ----------- |
| A **complete DevOps platform** with integrated CI/CD, package registry, security scanning, and enterprise features | **GitLab** |
| A **lightweight, easy-to-operate Git server** with minimal resource usage | **Gitea** |
| A **community-driven forge** similar to Gitea but with **built-in CI (Forgejo Actions)** and future **federation support** | **Forgejo** |
A more detailed comparison that covers forgejo specific features and limitations is available in the [forgejo.org/compare](https://forgejo.org/compare/).
## Forgejo vs. Gitea: What the Community Says
- [Same but different](https://forgejo.org/compare-to-gitea/). Forgejo is a hard fork of Gitea, so they share the same codebase and many features.
- However, Forgejo has a [more active development](https://honeypot.net/2025/05/14/gitea-vs-forgejo-development-activity.html) and a more open governance model, which allows it to evolve faster and to include features that are not present in Gitea (e.g. Forgejo Actions, ...)
- Many people and companies move from gitea to forgejo [reddit](https://www.reddit.com/r/selfhosted/comments/1rlrgbw/how_are_the_differences_between_gitea_and_forgejo/).
## Forgejo vs. Gitlab: What the Community Says
- Fedora moves to Forgejo: [Fedora Magazine](https://fedoramagazine.org/fedora-moves-towards-forgejo-a-unified-decision/)
- The Fedora Team compared intensively GitLab and Forgejo before choosing the latter. The report is [here](https://fedora-arc.readthedocs.io/en/latest/dist-git-comparison/index.html).
- Forgejo is prefered over GitLab by many Software specialists.
One of the reasons is that GitLab is a very resource intensive application (because i.a. its written in Ruby) and that it has a very complex architecture (many services, many dependencies).
Forgejo is written in Go (more efficient and state-of-the-art) and has a much simpler architecture.
- [ycombinator](https://news.ycombinator.com/item?id=46097220)
- lwn.net: [Forgejo vs GitHub vs gitlab](https://lwn.net/Articles/1041447/)
## Pricing
| Feature | GitLab | Gitea | Forgejo |
|-------------------------------------------|:------------------:|:-----------------:|:-------------------:|
| Free tier | ✅ | ✅ | ✅ |
| Paid tier (per user/month) | **premium**: 29\$
**ultimate**: on request | **enterprise**: 19\$ | ❌ (donation-based) |
| Information on pricing | [**info**](https://about.gitlab.com/pricing/?deployment=self-managed-deployment) | [**info**](https://about.gitea.com/pricing/) | [**info**](https://liberapay.com/forgejo) |
## Core Git Features
| Feature | GitLab | Gitea | Forgejo |
|---------------------------|:------:|:-----:|:-------:|
| Git repositories | ✅ | ✅ | ✅ |
| Git LFS support | ✅ | ✅ | ✅ |
| Git tags for releases | ✅ | ✅ | ✅ |
| Protected branches | ✅ | ✅ | ✅ |
| Repository mirroring | ✅ | ✅ | ✅ |
| Webhooks | ✅ | ✅ | ✅ |
## Collaboration and Project Management
| Feature | GitLab | Gitea | Forgejo |
|----------------------------------|:------:|:-----:|:-------:|
| Issues | ✅ | ✅ | ✅ |
| Pull / merge requests | ✅ | ✅ | ✅ |
| Pull request reviewer assignment | ✅ | ✅ | ✅ |
| Pull request inline comments | ✅ | ✅ | ✅ |
| Wiki (per repository) | ✅ | ✅ | ✅ |
| Snippets / gists | ✅ | ⚠️ limited | ⚠️ limited |
| Project management | **free**: simple kanban
**premium**: [roadmap](https://docs.gitlab.com/user/group/roadmap/) | [simple kanban](https://forum.gitea.com/t/gantt-diagrams-for-issues/788/3) | [simple kanban](https://forgejo.org/docs/next/user/project/) |
| Organization / group hierarchy | ✅ | ⚠️ simpler model | ⚠️ simpler model |
| Code search (global) | ✅ | ⚠️ limited | ⚠️ limited |
| Repository mirroring (push/pull) | ✅ | ✅ | ✅ |
## CI/CD and Automation
| Feature | GitLab | Gitea | Forgejo |
|--------------------------------|:------:|:-----:|:-------:|
| Built-in CI/CD | ✅built-in Gitlab CI/CD |️ ❌ external CI (woodpecker/Drone) | ✅Forgejo Actions (Github-Actions compatible) |
| Automated workflows | ✅ | ⚠️ external CI required | ✅ |
| Workflow triggers | ✅ | ⚠️ depends on CI integration | ✅ |
| External CI integration | ✅ | ✅ | ✅ |
## Artifacts & Registries
| Feature | GitLab | Gitea | Forgejo |
|---------------------------|:------:|:-----:|:-------:|
| Package registry | ✅ | ⚠️ limited ecosystem support | ✅ |
| Container registry | ✅ | ⚠️ plugin / external registry | ⚠️ evolving support |
## Authentication and Access Control
| Feature | GitLab | Gitea | Forgejo |
|------------------------------|:------:|:-----:|:-------:|
| Access control | ✅ | ✅ | ✅ |
| LDAP / Active Directory | ✅ | ✅ | ✅ |
| SAML / enterprise SSO | ⚠️ enterprise tier | ❌ not supported | ❌ not supported |
| Federation between instances | ❌ not supported | ❌ not supported | ⚠️ planned (ForgeFed) |
## Operations / Self-Hosting
| Feature | GitLab | Gitea | Forgejo |
|-----------------------|:------:|:-----:|:-------:|
| Resource footprint | ❌ heavy (many services) | ✅ light | ✅ light |
| Deployment complexity | ❌ complex | ✅ simple | ✅ simple |
# Notes on the test project setup:
## Gitea
- SSH is disabled by default, so we use HTTPS to clone the repository.
- it can be enabled in the Gitea settings if needed (see [here](https://forum.gitea.com/t/how-do-i-enable-ssh-on-a-gitea-self-hosted-instance/10044/3) and [here](https://forum.gitea.com/t/how-to-set-ssh-to-alow-users-with-gite-account-to-clone-via-ssh/2297/5))
- HTTPS: works, but requires the user to set a password manually in the profile first. That's unexpected since it should be inherited by authentik. Probably a misconfiguration from there.
## Forgejo
- SSH is disabled by default, so we use HTTPS to clone the repository. Same as with Gitea.
- HTTPS: Same as with Gitea.
## Gitlab
- SSH is active by default. But the port is wrongly configured and probably already used by the host...
- HTTPS: works well.