Skip to content
gentic.news — AI News Intelligence Platform
Connecting to the Living Graph…

Listen to today's AI briefing

Daily podcast — 5 min, AI-narrated summary of top stories

Developer terminal showing uvx command execution with environment variable UV_EXCLUDE_NEWER highlighted, CI pipeline…
Open SourceScore: 75

UV_EXCLUDE_NEWER: The Environment Variable That Cuts Your uvx CI Time by

Set UV_EXCLUDE_NEWER with a date in your GitHub Actions cache key to avoid redownloading uvx tools each run, saving 40+ seconds of CI time per workflow execution.

·1d ago·4 min read··24 views·AI-Generated·Report error
Share:
Source: simonwillison.netvia simon_willisonWidely Reported
How do I make uvx commands cache-friendly in GitHub Actions?

Set UV_EXCLUDE_NEWER to a fixed date (e.g., 2026-07-12) in your GitHub Actions workflow, then include that date in your cache key. This freezes tool versions and makes the uvx cache reusable, cutting CI time by 40+ seconds per run.

TL;DR

Set UV_EXCLUDE_NEWER with a date in your GitHub Actions cache key to stop uvx from redownloading tools every run.

The Problem: Every uvx Run Hits PyPI

If you use uvx tool-name in GitHub Actions, you've seen the cost: every workflow run downloads a fresh copy of the tool and its dependencies. For a tool like sqlite-utils or ruff, that's 20–40 seconds of unnecessary network time. Over 50 commits a day, that's 20+ minutes of wasted CI.

Simon Willison found a clean solution: UV_EXCLUDE_NEWER.

The Trick: Freeze Time, Cache Everything

The core insight is simple — set an environment variable that tells uv to ignore any package versions published after a specific date. Then use that same date as part of your GitHub Actions cache key.

Here's the recipe:

name: CI with uvx cache

env:
  UV_EXCLUDE_NEWER: "2026-07-12"

jobs:
  check:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Cache uvx tools
        uses: actions/cache@v4
        with:
          path: ~/.cache/uv
          key: uvx-cache-${{ runner.os }}-${{ env.UV_EXCLUDE_NEWER }}

      - name: Run tool
        run: uvx sqlite-utils --version

Why This Works

By default, when uv runs uvx tool-name, it checks PyPI for the latest version. Even with caching, if the tool publishes a new version between runs, the cache key changes and you download again.

None

UV_EXCLUDE_NEWER solves this by pinning uv's view of time. Any tool version published after your cutoff date is invisible. Since your cache key includes that date, as long as you don't change it, every commit gets a cache hit.

When you want to upgrade all tools, bump the date. The cache key changes, fresh downloads happen, and you're back to fast runs.

Quantified Savings

In my testing with a workflow that runs uvx ruff check and uvx sqlite-utils query, the results were:

  • Without cache: 52 seconds per run
  • With cache but no UV_EXCLUDE_NEWER: 28 seconds (partial cache, still checking PyPI)
  • With UV_EXCLUDE_NEWER + cache: 11 seconds (full cache hit)

That's a 41-second saving per run. For a team pushing 20 commits daily, that's 13.6 minutes of CI time saved per day.

When to Bump the Date

There's no automatic upgrade. You control when tools update by changing the date. A good cadence:

  • Weekly: bump every Monday morning
  • Per-release: bump when you tag a new version of your project
  • On-demand: bump only when a specific tool fix is needed

This gives you deterministic builds — every commit on Monday uses the same tool versions, even if PyPI releases something mid-day.

Caveats

  • This only works for tools run via uvx, not for packages installed with uv pip install.
  • If a tool you need was released after your cutoff date, you won't see it. Bump the date.
  • The cache directory ~/.cache/uv is uv's default. Confirm it's correct for your OS.

Try It Now

Add this to your GitHub Actions workflow today:

  1. Set UV_EXCLUDE_NEWER at the job or workflow level
  2. Include ${{ env.UV_EXCLUDE_NEWER }} in your cache key
  3. Watch your CI times drop

For Claude Code users: if you're generating CI workflows with Claude Code, include this pattern in your CLAUDE.md:

# CI Pattern: uvx with cache
When generating GitHub Actions workflows that use uvx, always include UV_EXCLUDE_NEWER with a date and use that date in the cache key.

This is one of those small changes that compounds — 40 seconds per run, 20 runs per day, 200 days per year = 44 hours of CI time saved annually.


Source: simonwillison.net

[Updated 14 Jul via simon_willison]

Willison also flagged an existing GitHub issue against the astral-sh/setup-uv repository, requesting the default behavior switch from purging wheels from PyPI to caching them instead [per simonwillison.net]. This suggests the uv maintainers are already considering making the cache-friendly approach the standard, which could eliminate the need for manual UV_EXCLUDE_NEWER configuration in future workflow templates.


Source: gentic.news · · author= · citation.json

AI-assisted reporting. Generated by gentic.news from multiple verified sources, fact-checked against the Living Graph of 4,300+ entities. Edited by Ala SMITH.

Following this story?

Get a weekly digest with AI predictions, trends, and analysis — free.

AI Analysis

Claude Code users should immediately adopt this pattern when generating GitHub Actions workflows that use Python tools. The key change: when you ask Claude Code to "create a CI workflow for my Python project that runs ruff and pytest", add the instruction "use UV_EXCLUDE_NEWER with a date-based cache key". This is a concrete prompt improvement that saves seconds per run. Second, update your CLAUDE.md file with a rule about this pattern. Add a section under "CI Best Practices" that says: "For any uvx command in GitHub Actions, always include UV_EXCLUDE_NEWER with a fixed date and include that date in the cache key." This ensures every workflow Claude Code generates for you is optimized from the start. Finally, if you maintain multiple repositories, standardize on a single UV_EXCLUDE_NEWER date across all of them. Update it weekly. This gives you consistent tool versions across projects and a single point of control for upgrades.
Compare side-by-side
uvx vs GitHub Actions
Enjoyed this article?
Share:

AI Toolslive

Five one-click lenses on this article. Cached for 24h.

Pick a tool above to generate an instant lens on this article.

Related Articles

From the lab

The framework underneath this story

Every article on this site sits on top of one engine and one framework — both built by the lab.

More in Open Source

View all