Skip to main content

Pedram Sarani

SRE / DevOps Notes

FA
Back to articles

GitLab CI Pipeline Optimization for Large Monorepos

Design GitLab CI/CD pipelines around fast feedback, runner capacity, cache correctness, and deployment safety.

Baseline before optimization

Do not start with YAML cleanup. Start with the signals that show whether the delivery system is healthy:

  • Median pipeline duration by branch type
  • P95 merge request validation time
  • Queue wait time per runner class
  • Retry rate caused by flaky jobs
  • Cache hit rate for dependency-heavy jobs

Without this baseline, optimizations are guesswork.

Pipeline topology: split critical vs non-critical paths

Separate the developer feedback path from slower governance and release steps. Merge requests need a short path to useful failure. Protected branches can afford deeper verification.

stages:
  - lint
  - test
  - package
  - security
  - deploy

unit-tests:
  stage: test
  needs: ["lint"]
  script: ["npm ci", "npm run test:unit"]

integration-tests:
  stage: test
  needs: ["package"]
  script: ["./scripts/integration.sh"]

Use needs to unlock parallelism while preserving correctness. Avoid hidden ordering through shared artifacts; every dependency should be visible in the pipeline graph.

Cache strategy that actually works

A common anti-pattern is one global cache key with heavy churn. Prefer targeted cache keys:

  • Lockfile hash for language dependencies
  • Toolchain version in key prefix
  • Distinct paths for build artifacts vs dependency caches

This improves cache hit ratio and avoids cache poisoning across branches. Treat cache invalidation as a reliability concern, not a performance-only optimization.

Runner and cost governance

  • Route heavy jobs to isolated or autoscaled ephemeral runners.
  • Keep lightweight checks on shared runners with strict concurrency.
  • Enforce timeout budgets per job type.
  • Alert on queue time and runner failure rate before teams start adding unsafe retries.

Merge request experience improvements

Fast-fail checks first

Run static validation, schema checks, and policy linting before expensive integration tests.

Optional test partitions

Use risk-based partitions for medium-sized changes while keeping full suites on protected branches. If a partition is allowed to skip tests, make the rule explicit and visible in review.

Final recommendation

Treat your pipeline as a production system with SLOs. Queue time, retry rate, cache behavior, and deployment rollback readiness should be reviewed with the same discipline as service reliability signals.