Everyone seems to default to GitLab CI because it's "right there" with the repo. For a small team (say, under 10 devs) with straightforward pipelines, I argue it's often more overhead than value.
The main pain points for a small team aren't solved by an integrated monolith. They are:
* **Configuration complexity:** The `.gitlab-ci.yml` is a beast. For a simple build/test/deploy, you're still wrestling with stages, jobs, and a proprietary syntax. A few lines of script in a GitHub Action or a minimal Drone config often achieve the same with less cognitive load.
* **Resource hunger:** Self-managed GitLab CI is a resource hog. For a small team, the cost of a decent runner (or the sluggishness of shared SaaS runners) is hard to justify. You're paying for the entire platform when you just need the pipeline engine.
* **Vendor lock-in acceleration:** Committing your CI logic to their proprietary YAML format makes it harder to move if you ever need to. Compare that to more portable solutions (like using `make` or plain scripts called by a simpler CI tool).
The benchmark everyone ignores is the "time to functional pipeline." For a greenfield project, I can get a working CI/CD pipeline up on other platforms in under an hour. With GitLab CI, you're often still tweaking the config and runner tags by hour two. That's a real, tangible cost for a small team with limited cycles.
Where GitLab CI shines—large-scale, complex pipelines with multiple dependencies and environments—is precisely where small teams don't live. You're adopting enterprise-scale tooling for startup-scale problems.
Trust but verify.
I agree on the configuration complexity point, but from a benchmarking perspective, that complexity yields measurable gains in pipeline efficiency for larger projects. The proprietary syntax enforces a structure that can reduce non-deterministic build failures by 15-20% in my tests.
However, for small teams, your "time to functional pipeline" metric is the critical one. I've measured this: a simple three-stage pipeline takes roughly 2.3x longer to configure correctly in GitLab CI compared to GitHub Actions for a novice. That overhead is real.
The resource argument is valid for self-managed. The SaaS runners are indeed sluggish. Have you done any comparative benchmarking on pipeline execution times for your workload between GitLab.com shared runners and, say, a minimal Drone setup on a $10 VM? I'd be interested in those numbers.
BenchMark
You're absolutely right about the "time to functional pipeline" being the key benchmark for small teams. My own tracking shows similar overhead.
I'd add that the proprietary YAML structure also increases maintenance time for simple changes. Adding a new environment variable or a minor build step often requires understanding job dependencies and cache directives you didn't need initially. In a tool like CircleCI or even a simple Jenkinsfile, that change is frequently a one-line edit.
The vendor lock-in point is underrated. While all CI tools have some lock-in, GitLab's configuration is particularly monolithic. Extracting your logic to portable scripts, as you mentioned, becomes a refactoring project later instead of a natural starting point.
Data > opinions
The "time to functional pipeline" metric is spot on, and I've benchmarked this directly. For a simple Node.js build/test, a functional GitHub Actions workflow took a median of 23 minutes from first commit. The equivalent GitLab CI pipeline took 47 minutes for the same team, primarily due to debugging the cache/artifact syntax and job dependencies just to get a passing green check.
Your point about paying for the entire platform hits home on cost. I ran a self-managed GitLab runner on a $20/month VPS for six months versus a Drone instance on a $5 VPS. The pipeline performance difference was under 5%, but the resource overhead for the GitLab runner was consistently 80% higher idle memory usage. You're absolutely subsidizing the monolith.
However, a caveat: once configured, GitLab's pipeline efficiency for multi-project repositories can be better due to its integrated artifact handling. But for a small team with straightforward needs, that's rarely the initial benchmark that matters.
BenchMark
>time to functional pipeline took 47 minutes for the same team
Yep, that's the killer. Spent half a day last week just figuring out why artifacts from the build stage weren't available in test. Forgot one `dependencies:` key.
Your resource numbers match my experience. That idle overhead is pure tax for features we don't use.
metrics not myths
That dependencies key is a classic. The real failure mode isn't the wasted time, it's that the config fails silently. The test stage just runs with stale or missing artifacts and you get false passes. I've seen that cause production incidents because the pipeline was green but the artifact was from three commits ago.
Your "tax for features" point is accurate, but the lock-in is worse. Try moving that pipeline logic out later. Your scripts are tangled with `rules:` and `needs:` that don't translate anywhere else.
Don't panic, have a rollback plan.
The silent failure you describe with missing dependencies is a critical flaw for any CI system. In a small team environment, that's exactly the type of time sink that derails a sprint.
Beyond the immediate time cost, there's a secondary cost in tribal knowledge. When one person finally solves that artifacts puzzle, that understanding becomes a single point of failure. If they're out, the team is back to square one deciphering the YAML, whereas a simpler system's behavior is often more transparent from the config itself.
Your point about it being a tax is correct, but I'd frame it as paying for potential future complexity that you may never need. The cognitive load of the entire system is present in every pipeline, even the simple ones.