uv-prune
Clean uv cache by removing non-hardlinked archive entries.
Problem
uv uses hard links to deduplicate package data across different Python versions and projects. When a package is no longer used by any project, its archive entry remains on disk but is no longer referenced by any other hard link.
uv-prune scans the archive-v0 directory in uv's cache and removes entries whose files have a link count of 1 — meaning they are no longer shared and can be safely deleted.
How it works
For each entry in archive-v0, uv-prune:
- Looks for a
.dist-infosubdirectory to identify the package name and version (e.g.anyio-4.0.0fromanyio-4.0.0.dist-info). - Checks the link count of the
METADATAfile inside that directory — uv hard-links this file across all environments that share the package. - If the link count is 1, the archive entry is no longer shared and is removed. If it is > 1, the entry is still in use and is kept.
- Entries without a
.dist-infodirectory are only warned about by default; pass--include-no-dist-infoto remove them too.
All entries are processed in parallel (via Rayon) and reported as a table sorted by package name and version.
Installation
From PyPI (pre-built binary)
Every tagged release publishes platform wheels to PyPI (the compiled binary ships inside a thin Python launcher package, so the bin directory gets a small launcher instead of a full copy of the executable), so install with any Python package manager:
uv tool install uv-prune # recommended — managed by uv
pipx install uv-prune
pip install uv-prune # then run `uv-prune`
From GitHub Releases
Pre-built binaries for Linux (x86_64 / aarch64, static musl), macOS (arm64 / x86_64) and Windows (x86_64 / arm64) are attached to each release as .tar.gz / .zip archives together with a SHA256SUMS checksum file.
From source
cargo install uv-prune
Or build manually:
git clone https://github.com/QiE2035/uv-prune
cd uv-prune
cargo build --release
Releases
Pushing a v* tag triggers the publish workflow, which:
- Builds release binaries for Linux (musl), macOS and Windows (see the platform table in the workflow).
- Creates (or updates) a GitHub Release with the archives and
SHA256SUMS. - Builds
py3-none-{platform}wheels from those binaries and publishes them to PyPI — via trusted publishing (recommended), or thePYPI_API_TOKENrepository secret as fallback.
git tag v0.1.1
git push origin v0.1.1
The workflow can also be run manually via workflow_dispatch to smoke-test the build matrix without publishing.
--version reports build provenance: local development builds get +dev.<short-sha> (e.g. uv-prune 0.1.0+dev.a1b2c3d4), CI builds of main get +ci.<run-number>.<commit-sha-prefix> (e.g. uv-prune 0.1.0+ci.42.a1b2c3d4), and tagged releases stay clean (uv-prune 0.1.0).
Usage
# Prune with default cache path
uv-prune
# Dry-run — see what would be deleted without actually deleting
uv-prune --dry-run
# Verbose output
uv-prune --verbose
# Custom cache directory
uv-prune --cache-dir /path/to/uv/cache
# Also remove entries without .dist-info (default: warn only)
uv-prune --include-no-dist-info
# Disable timing measurement
uv-prune --no-timing
# Set number of parallel workers
uv-prune --jobs 4
Options
| Option | Short | Description |
|---|---|---|
--cache-dir <DIR> |
-c |
UV cache directory (overrides UV_CACHE_DIR env var) |
--dry-run |
-d |
Show what would be deleted without actually deleting |
--verbose |
-v |
Enable verbose (debug) output |
--include-no-dist-info |
-i |
Also remove entries without a .dist-info directory |
--jobs <N> |
-j |
Number of parallel workers (0 = auto-detect, default) |
--no-timing |
-n |
Disable timing measurement |
Exit Codes
| Code | Meaning |
|---|---|
0 |
Success (even if entries were skipped/warned) |
1 |
One or more errors occurred while pruning |
Environment Variables
| Variable | Description |
|---|---|
UV_CACHE_DIR |
Override the uv cache directory path |
RUST_LOG |
Control log level (e.g., debug, info, warn, error) |
Cache Directory Resolution
--cache-dirCLI argumentUV_CACHE_DIRenvironment variable- Platform default:
- Windows:
%LOCALAPPDATA%\uv\cache - Linux / macOS:
~/.cache/uv(or$XDG_CACHE_HOME/uv)
- Windows:
Output Example
$ uv-prune --dry-run --verbose
[INFO uv_prune] uv-prune v0.1.0 — cache: /home/user/.cache/uv
[INFO uv_prune::prune] Pruning archive directory: /home/user/.cache/uv/archive-v0
[INFO uv_prune::prune] Dry-run mode — no files will be deleted
[INFO uv_prune::prune] [DRY-RUN] Action ID Version Name Detail
[INFO uv_prune::prune] [DRY-RUN] -------- --------------------- -------- --------- -----------------------------------------
[INFO uv_prune::prune] [DRY-RUN] Deleting abc123def456789abc 4.0.0 anyio
[DEBUG uv_prune::prune] [DRY-RUN] Keeping ghi012jkl345mnopqr 2.31.0 requests
[WARN uv_prune::prune] [DRY-RUN] Skipping deadbeef - - no .dist-info (use --include-no-dist-info to remove)
[INFO uv_prune::prune] Done: 3 checked, 1 removed, 2 skipped, 1 no-dist-info, 0 errors
[INFO uv_prune] Elapsed time: 15.2ms
The report is a table with the following columns:
- Action —
Deleting,Keeping,SkippingorFailed. - ID — the uv cache archive directory name;
-when it could not be read. - Version / Name — parsed from the
.dist-infodirectory name;-when there is no.dist-info. - Detail — the reason for
Skipping/Failedentries, if any.
In dry-run mode every table line is prefixed with [DRY-RUN] and nothing is actually deleted. Keeping rows are logged at debug level, so pass --verbose to see them, and column widths adapt to the longest entry.
Platform Support
| Platform | Hard link detection |
|---|---|
| Windows | GetFileInformationByHandle → nNumberOfLinks |
| Linux | stat → st_nlink via std::os::unix::fs::MetadataExt |
| macOS | stat → st_nlink via std::os::unix::fs::MetadataExt |
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distributions
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file uv_prune-0.1.1-py3-none-win_arm64.whl.
File metadata
- Download URL: uv_prune-0.1.1-py3-none-win_arm64.whl
- Upload date:
- Size: 603.1 kB
- Tags: Python 3, Windows ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bc7e8201c3021ea33779c8d76e96c013db3e8e468a7599e6eef88eff77d79611
|
|
| MD5 |
6666ee4fc8ce5db09ad6d53a52e210f4
|
|
| BLAKE2b-256 |
6f36316d872431e0e49c938d34f228afd6819286eb7f3a17c53af48d9af8ca0c
|
Provenance
The following attestation bundles were made for uv_prune-0.1.1-py3-none-win_arm64.whl:
Publisher:
publish.yml on QiE2035/uv-prune
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
uv_prune-0.1.1-py3-none-win_arm64.whl -
Subject digest:
bc7e8201c3021ea33779c8d76e96c013db3e8e468a7599e6eef88eff77d79611 - Sigstore transparency entry: 2363348509
- Sigstore integration time:
-
Permalink:
QiE2035/uv-prune@d4477bb1bff3ce0b48d6ff0588bc53f2fe7c4b61 -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/QiE2035
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@d4477bb1bff3ce0b48d6ff0588bc53f2fe7c4b61 -
Trigger Event:
push
-
Statement type:
File details
Details for the file uv_prune-0.1.1-py3-none-win_amd64.whl.
File metadata
- Download URL: uv_prune-0.1.1-py3-none-win_amd64.whl
- Upload date:
- Size: 659.1 kB
- Tags: Python 3, Windows x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ba9551828404133c7080b763b7f1636ac9da44decd168d57d3ee3f0079c61fa3
|
|
| MD5 |
4b1b7c09c80326875b7b97cc3b55462a
|
|
| BLAKE2b-256 |
a9af96750378446feb261cf981dc9a8d2ab6fd15966c0c2953e66694e1f47e8a
|
Provenance
The following attestation bundles were made for uv_prune-0.1.1-py3-none-win_amd64.whl:
Publisher:
publish.yml on QiE2035/uv-prune
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
uv_prune-0.1.1-py3-none-win_amd64.whl -
Subject digest:
ba9551828404133c7080b763b7f1636ac9da44decd168d57d3ee3f0079c61fa3 - Sigstore transparency entry: 2363348856
- Sigstore integration time:
-
Permalink:
QiE2035/uv-prune@d4477bb1bff3ce0b48d6ff0588bc53f2fe7c4b61 -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/QiE2035
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@d4477bb1bff3ce0b48d6ff0588bc53f2fe7c4b61 -
Trigger Event:
push
-
Statement type:
File details
Details for the file uv_prune-0.1.1-py3-none-musllinux_1_2_x86_64.whl.
File metadata
- Download URL: uv_prune-0.1.1-py3-none-musllinux_1_2_x86_64.whl
- Upload date:
- Size: 819.3 kB
- Tags: Python 3, musllinux: musl 1.2+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
353a5b724cd81eadce79936216cc2c56f4cf74fc4f2032b5999d6cbf2245fba8
|
|
| MD5 |
6fa50f2c42171f247f9f738008ff3baa
|
|
| BLAKE2b-256 |
d883b39373f84b247e3913b8159d89e10dee324bfd114e5dfb18c6e6f6fae24e
|
Provenance
The following attestation bundles were made for uv_prune-0.1.1-py3-none-musllinux_1_2_x86_64.whl:
Publisher:
publish.yml on QiE2035/uv-prune
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
uv_prune-0.1.1-py3-none-musllinux_1_2_x86_64.whl -
Subject digest:
353a5b724cd81eadce79936216cc2c56f4cf74fc4f2032b5999d6cbf2245fba8 - Sigstore transparency entry: 2363350282
- Sigstore integration time:
-
Permalink:
QiE2035/uv-prune@d4477bb1bff3ce0b48d6ff0588bc53f2fe7c4b61 -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/QiE2035
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@d4477bb1bff3ce0b48d6ff0588bc53f2fe7c4b61 -
Trigger Event:
push
-
Statement type:
File details
Details for the file uv_prune-0.1.1-py3-none-musllinux_1_2_aarch64.whl.
File metadata
- Download URL: uv_prune-0.1.1-py3-none-musllinux_1_2_aarch64.whl
- Upload date:
- Size: 740.1 kB
- Tags: Python 3, musllinux: musl 1.2+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b17641cf70ec558569be5ec5a73ce8fa80b44466f141c96a5a8221320e7b1c81
|
|
| MD5 |
788ba59038ba7eaf5d89a366689721a9
|
|
| BLAKE2b-256 |
6d80a71a55b2e6b73193bfc068b63296ed03d4de0207ee666fd41b9f184d4bb9
|
Provenance
The following attestation bundles were made for uv_prune-0.1.1-py3-none-musllinux_1_2_aarch64.whl:
Publisher:
publish.yml on QiE2035/uv-prune
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
uv_prune-0.1.1-py3-none-musllinux_1_2_aarch64.whl -
Subject digest:
b17641cf70ec558569be5ec5a73ce8fa80b44466f141c96a5a8221320e7b1c81 - Sigstore transparency entry: 2363349185
- Sigstore integration time:
-
Permalink:
QiE2035/uv-prune@d4477bb1bff3ce0b48d6ff0588bc53f2fe7c4b61 -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/QiE2035
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@d4477bb1bff3ce0b48d6ff0588bc53f2fe7c4b61 -
Trigger Event:
push
-
Statement type:
File details
Details for the file uv_prune-0.1.1-py3-none-macosx_11_0_arm64.whl.
File metadata
- Download URL: uv_prune-0.1.1-py3-none-macosx_11_0_arm64.whl
- Upload date:
- Size: 637.0 kB
- Tags: Python 3, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6d712d42f5081c0db89355d05b54cdf6d09352a2c7895997c416316e85e5bad6
|
|
| MD5 |
092bd6df8974734757f14db4038ce0e9
|
|
| BLAKE2b-256 |
5ad964cbc8c6320c1ee6ff6e70a07eeaa4bc944ba29dcfc759a02e456a2c3155
|
Provenance
The following attestation bundles were made for uv_prune-0.1.1-py3-none-macosx_11_0_arm64.whl:
Publisher:
publish.yml on QiE2035/uv-prune
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
uv_prune-0.1.1-py3-none-macosx_11_0_arm64.whl -
Subject digest:
6d712d42f5081c0db89355d05b54cdf6d09352a2c7895997c416316e85e5bad6 - Sigstore transparency entry: 2363349648
- Sigstore integration time:
-
Permalink:
QiE2035/uv-prune@d4477bb1bff3ce0b48d6ff0588bc53f2fe7c4b61 -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/QiE2035
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@d4477bb1bff3ce0b48d6ff0588bc53f2fe7c4b61 -
Trigger Event:
push
-
Statement type:
File details
Details for the file uv_prune-0.1.1-py3-none-macosx_10_12_x86_64.whl.
File metadata
- Download URL: uv_prune-0.1.1-py3-none-macosx_10_12_x86_64.whl
- Upload date:
- Size: 720.8 kB
- Tags: Python 3, macOS 10.12+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8dc9fbd72bf37b9e8d6fa09897239eb5aaf3dcde0fbff9c8e1ed8fb1234e4e99
|
|
| MD5 |
f0edf0ca4772d9b42a2cff19d1999d13
|
|
| BLAKE2b-256 |
ed70a00d8a05fe735334dfa4eda1f35b4f0803b770f95882df9f6b1ddda965a2
|
Provenance
The following attestation bundles were made for uv_prune-0.1.1-py3-none-macosx_10_12_x86_64.whl:
Publisher:
publish.yml on QiE2035/uv-prune
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
uv_prune-0.1.1-py3-none-macosx_10_12_x86_64.whl -
Subject digest:
8dc9fbd72bf37b9e8d6fa09897239eb5aaf3dcde0fbff9c8e1ed8fb1234e4e99 - Sigstore transparency entry: 2363348086
- Sigstore integration time:
-
Permalink:
QiE2035/uv-prune@d4477bb1bff3ce0b48d6ff0588bc53f2fe7c4b61 -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/QiE2035
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@d4477bb1bff3ce0b48d6ff0588bc53f2fe7c4b61 -
Trigger Event:
push
-
Statement type: