Skip to content

How to Configure Caching in GitLab CI

DodaTech 2 min read

In this tutorial, you'll learn about How to Configure Caching in GitLab CI. We cover key concepts, practical examples, and best practices.

The Problem

Your GitLab CI pipeline installs dependencies from scratch in every job, making builds slow. Caching saves downloaded packages so subsequent jobs and pipelines reuse them.

Quick Fix

Step 1: Cache npm dependencies

cache:
  key: $CI_COMMIT_REF_SLUG
  paths:
    - node_modules/

This caches the node_modules directory per branch. The cache is restored at the start of each job and uploaded when the job completes.

Step 2: Cache with lockfile-based key

cache:
  key:
    files:
      - package-lock.json
    prefix: npm-cache
  paths:
    - node_modules/

The cache is invalidated when package-lock.json changes. The prefix allows multiple caches with different prefixes.

Step 3: Cache pip dependencies

cache:
  key:
    files:
      - requirements.txt
    prefix: pip-cache
  paths:
    - ~/.cache/pip/

Step 4: Cache between stages (with policy)

stages:
  - install
  - test

install_deps:
  stage: install
  cache:
    key: $CI_COMMIT_REF_SLUG
    paths:
      - node_modules/
    policy: push
  script:
    - npm ci

run_tests:
  stage: test
  cache:
    key: $CI_COMMIT_REF_SLUG
    paths:
      - node_modules/
    policy: pull
  script:
    - npm test

policy: push only uploads the cache. policy: pull only downloads it. This prevents race conditions when multiple jobs write to the same cache.

Step 5: Use artifacts to pass built files between stages

build:
  stage: build
  artifacts:
    paths:
      - dist/
    expire_in: 1 hour
  script:
    - npm run build

deploy:
  stage: deploy
  needs: [build]
  script:
    - rsync -avz dist/ server:/var/www/

Artifacts pass files between jobs within the same pipeline. Unlike cache, artifacts are guaranteed fresh for each pipeline.

Step 6: Per-job cache override

test:
  cache:
    key: $CI_COMMIT_REF_SLUG
    paths:
      - node_modules/
    policy: pull
  script:
    - npm test

Override the global cache section in individual jobs when different caches are needed.

Step 7: Clear the cache

Push an empty commit with [ci skip] or use the GitLab UI: CI/CD > Pipeline Cache > Clear.

Alternative Solutions

Use GIT_<a href="/design-patterns/strategy/">Strategy</a>: clone with shallow fetch for smaller repo clones, combined with cache for dependencies.

Common Errors

Cache not restored: If the cache key does not match any existing cache, the job downloads dependencies from scratch. Use key: "$CI_COMMIT_REF_SLUG-$CI_JOB_NAME" for more precise matching.

Cache upload fails with archive error: Large caches (>500 MB) can time out. Exclude unnecessary directories: paths: [node_modules/] instead of the entire project.

Cache interference between parallel jobs: Two jobs running in parallel with the same cache key can corrupt each other's cache. Use different keys or policy: pull for test-only jobs.

Stale cache: If dependencies were updated but the cache key did not change, old cached files are reused. Include a lockfile hash in the cache key for automatic invalidation.

Prevention

  • Use policy: pull in test jobs and policy: push in install jobs to avoid race conditions.
  • Set cache keys based on lockfile content for automatic invalidation.
  • Monitor cache size in the GitLab project settings.
  • Do not cache large build artifacts — use artifacts with expire_in instead.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro