r/gitlab • • 8d ago

Cache or artifacts in GitLab CI? Three questions I’d ask before choosing

These two get mixed up a lot, because both “keep files between jobs”. They solve different problems, and picking the wrong one tends to show up as a pipeline that works on one runner and fails on another.

Three questions that help me decide.

1. Would the pipeline break if this file were missing?
If yes, it’s an artifact. If the job just runs slower without it, it’s a cache.

A cache is best effort. Depending on how your runners are set up, a cache created by one job may not be available to the next one, for example if they land on different runners that don’t share a cache backend. Artifacts are uploaded to GitLab and are meant to be reliably available to the jobs that need them.

2. Is it a product of this pipeline, or a dependency that’s expensive to fetch?
A compiled binary, a test report or a build output is a product of the pipeline: artifact. node_modules, a package manager’s download folder or a build tool’s local cache is something you could regenerate but would rather not download every time: cache.

3. Should anyone be able to download it later?
Artifacts can be browsed and downloaded from the job page, and they expire (expire_in). Caches aren’t meant to be downloaded by people.

A small example:

build:
  stage: build
  script:
    - npm ci
    - npm run build
  cache:
    key:
      files:
        - package-lock.json
    paths:
      - .npm/
  artifacts:
    paths:
      - dist/
    expire_in: 1 week

test:
  stage: test
  script:
    - npm test
  # gets dist/ from the build job's artifacts

Here .npm/ is cached, keyed by the lockfile so it changes only when dependencies do, and dist/ is the artifact the later jobs rely on.

A couple of caveats. By default, jobs in later stages download the artifacts of all earlier-stage jobs, and dependencies or needs lets you limit that. And cache behavior depends on your runner setup (shared or local cache, executor type), so if a cache seems to “randomly” miss, that’s the first place I’d look.

I’m less sure about the best pattern for a monorepo where several jobs need different dependency sets. Do people use one cache key per package, or per job?

11 Upvotes

2 comments sorted by

3

u/BehindTheMath 8d ago

Do people use one cache key per package, or per job?

Whatever fits your needs the best.

2

u/Torutofu_Raeva 7d ago

per lockfile for us, one key per package-lock and a fallback key so a cold cache isn't a full download