How to cache pip dependencies in GitHub Actions (one line)
Every uncached Python workflow pays the same tax: pip re-downloads and re-resolves the same requirements on every single run. The fix is one line on the setup step you already have, and it is probably the highest ratio of savings to effort in all of GitHub Actions.
The one line
- uses: actions/setup-python@v5
with:
python-version: '3.12'
cache: 'pip'That is the whole fix for most projects. setup-python caches pip's download cache keyed on your requirements files and restores it before your install step. Wheels stop re-downloading; install time drops to unpacking.
What it caches (and what it doesn't)
cache: 'pip' caches pip's wheel cache, not your installed environment. Your pip install still runs, it just hits local wheels instead of PyPI. That is the right trade: the environment stays reproducible, only the network round-trips disappear. By default the cache key hashes requirements*.txt in the repo root; if your requirements live elsewhere, point at them:
- uses: actions/setup-python@v5
with:
python-version: '3.12'
cache: 'pip'
cache-dependency-path: |
requirements/*.txt
setup.cfgPoetry and uv
setup-python also accepts cache: 'poetry' (with Poetry installed first). If you have moved to uv, its own setup action ships caching too — this is what flask does now: its test workflow runs uv with enable-cache: true instead of a bare pip install.
- uses: astral-sh/setup-uv@v4
with:
enable-cache: trueEven careful projects skip this
scrapy, one of the most-used Python packages there is, runs its Ubuntu test workflow with setup-python and a plain pip install -U tox — no cache: option, no actions/cache step, at the time of writing. Across a matrix that covers five Python versions plus PyPy, that is the same downloads over and over. If it hides there, check yours. See how other popular Python repos run CI →
These hide across however many workflow files you have, which is exactly why nobody sits down and fixes them. Point GitSpider at your repo and it flags which patterns apply, with the fix for each.
Scan your repo free