After years of working with GitLab CI/CD in various projects, here are five practices that consistently deliver faster, more reliable pipelines.

1. Use Caching Wisely

Cache dependencies between jobs to avoid re-downloading them every time:

cache:
  key: ${CI_COMMIT_REF_SLUG}
  paths:
    - node_modules/
    - .npm/

The key ensures different branches have separate caches, preventing conflicts.

2. Parallelize Your Tests

Split your test suite across multiple jobs:

test:
  parallel: 4
  script:
    - npm run test -- --shard=$CI_NODE_INDEX/$CI_NODE_TOTAL

This can reduce test time from 20 minutes to 5 minutes.

3. Use rules: Instead of only/except

The newer rules: syntax is more powerful and readable:

deploy:
  rules:
    - if: $CI_COMMIT_BRANCH == "main"
      when: on_success
    - when: never

4. Optimize Docker Images

Use small base images and multi-stage builds. Alpine-based images can be 10x smaller than Ubuntu-based ones.

5. Fail Fast

Put quick checks (linting, formatting) at the beginning of your pipeline. No point running a 20-minute test suite if the code doesn’t even compile.


What are your favorite CI/CD optimizations? We’d love to hear about them.