GitHub Actions pip Cache Not Working for Python Projects

In GitHub Actions workflows for Python projects, pip install times are slow and it appears that the pip cache is not being used between workflow runs. Even when using the actions/cache step, dependencies are reinstalled from scratch. How can pip caching be enabled and made effective in GitHub Actions?

Solution

To enable pip cache in GitHub Actions, you need to cache the pip cache directory. For most systems, this is ~/.cache/pip. Here is an example of how to do this:

- name: Cache pip
  uses: actions/cache@v4
  with:
    path: ~/.cache/pip
    key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
    restore-keys: |
      ${{ runner.os }}-pip-

- name: Install dependencies
  run: pip install -r requirements.txt

Make sure the cache key includes a hash of your requirements file. This will ensure the cache is updated when dependencies change. If you use pip install --no-cache-dir, remove that flag to allow caching.

Alternative #1

I've found that sometimes the cache key strategy needs to be more granular. If you have multiple Python versions or different dependency files, you should include them in the cache key:

- name: Cache pip
  uses: actions/cache@v4
  with:
    path: ~/.cache/pip
    key: ${{ runner.os }}-pip-${{ runner.python-version }}-${{ hashFiles('**/requirements*.txt') }}
    restore-keys: |
      ${{ runner.os }}-pip-${{ runner.python-version }}-
      ${{ runner.os }}-pip-

This ensures separate caches for different Python versions and dependency files, which can significantly improve cache hit rates.

Alternative #2

If you're using Poetry instead of pip, the cache location is different. You need to cache the Poetry cache directory:

- name: Cache Poetry
  uses: actions/cache@v4
  with:
    path: ~/.cache/pypoetry
    key: ${{ runner.os }}-poetry-${{ hashFiles('**/pyproject.toml') }}
    restore-keys: |
      ${{ runner.os }}-poetry-

- name: Install dependencies
  run: poetry install

This is especially useful if you're migrating from pip to Poetry or using both in different projects.

Alternative #3

For monorepos or projects with multiple dependency files, you might want to cache each directory separately:

- name: Cache pip for backend
  uses: actions/cache@v4
  with:
    path: backend/.cache/pip
    key: ${{ runner.os }}-pip-backend-${{ hashFiles('backend/requirements.txt') }}

- name: Cache pip for frontend
  uses: actions/cache@v4
  with:
    path: frontend/.cache/pip
    key: ${{ runner.os }}-pip-frontend-${{ hashFiles('frontend/requirements.txt') }}

This approach gives you more granular control over caching and can be more efficient for large projects with many dependencies.

Last modified: July 3, 2025
Stay in the loop
Subscribe to our newsletter to get the latest articles delivered to your inbox