astral-sh/uv
uv-cache
crates/uv-cache/ owns uv's on-disk cache. Almost everything in uv that is expensive to
compute or download is cached, and the layout, locking, and removal of those caches are
handled here.
Purpose
A unified, versioned cache that backs:
- HTTP responses from registries (Simple API, JSON API, sidecar metadata).
- Unpacked wheel archives ready for hard-linking into venvs.
- Built source distributions (with their build context and resulting wheels).
- Interpreter query results.
- Git checkouts.
- Cross-process locking primitives so multiple uv processes can share the cache safely.
The default location is ~/.cache/uv on Linux, ~/Library/Caches/uv on macOS, and
%LOCALAPPDATA%\uv\cache on Windows. It can be overridden with --cache-dir or
UV_CACHE_DIR.
Directory layout
crates/uv-cache/src/
├── lib.rs # 1461 lines: Cache, CacheBucket, CacheEntry, CacheShard, locking
├── archive.rs # ArchiveId — the symlink target for unpacked wheels
├── by_timestamp.rs # CachedByTimestamp<T> wrapper for time-based invalidation
├── cli.rs # CacheArgs (Clap), gated on the `clap` feature
├── removal.rs # rm_rf and Remover with progress accounting
└── wheel.rs # WheelCache + WheelCacheKind for distribution-aware bucketsThe cache directory itself looks like:
~/.cache/uv/
├── CACHEDIR.TAG # Standard cache-dir marker
├── archive-v0/ # Unpacked wheels, content-addressed
├── built-wheels-v0/ # Wheels built from sdists
├── git-v0/ # Git checkouts
├── interpreter-v$N/ # Cached interpreter query results
├── simple-v$N/ # PyPI Simple API responses
├── wheels-v$N/ # Downloaded wheel files
├── sdists-v$N/ # Downloaded sdists
└── flat-index-v$N/ # Flat-index responsesEach top-level directory is a cache bucket. Buckets are versioned (the Vn suffix in
crates/uv-cache/src/lib.rs::CacheBucket::to_str); bumping the version invalidates all entries
without needing a migration.
Key abstractions
| Type | File | Role |
|---|---|---|
Cache |
lib.rs |
Top-level handle. Owns the cache root and the Refresh policy. |
Refresh |
lib.rs |
Per-package refresh policy: refresh nothing, refresh specific packages, or refresh everything. |
CacheBucket |
lib.rs |
Enum naming each bucket (Simple, Wheels, Sdists, BuiltWheels, Interpreter, Git, FlatIndex, Archive). |
CacheEntry |
lib.rs |
A specific file within a bucket. Knows its directory, file name, and how to acquire a lock. |
CacheShard |
lib.rs |
A subdirectory within a bucket, scoped to a package or distribution. |
WheelCache |
wheel.rs |
Resolves the right cache shard for a wheel given its index source (registry, url, path, git). |
ArchiveId |
archive.rs |
The content-addressed identifier for an unpacked wheel. The cache stores a symlink → archive directory. |
CachedByTimestamp<T> |
by_timestamp.rs |
Wrapper that records a Timestamp alongside a value so consumers can detect staleness. |
Remover / Removal |
removal.rs |
Recursive-delete with size/file accounting. Used by uv cache prune and uv cache clean. |
Error |
lib.rs |
Cache I/O / locking errors. |
How it works
Bucket layout
A CacheBucket is a versioned directory under the cache root. Each entry within a bucket is
keyed by a stable hash of the source (URL + filename + version + …). Reads are lock-free
(open the file, mmap if needed); writes acquire an exclusive LockedFile via
uv-fs so concurrent uv processes don't corrupt each other.
Archive storage
Wheels are stored twice:
- As the original
.whlbyte-for-byte underwheels-vN/(so--link-mode=copyand HTTP resume work). - As an unpacked archive under
archive-v0/(so--link-mode=hardlink/clonecan directly link from the cache).
The unpacked archive uses ArchiveId (a content-addressed name) and is referenced by symlinks
from per-distribution shards. This deduplicates wheels that are bit-identical even when fetched
from different URLs.
Locking
CacheEntry::lock (and CacheShard::lock) wraps uv_fs::LockedFile::acquire to acquire an
OS-level file lock with LockedFileMode::Exclusive. The lock is held for the duration of the
write and released when the caller drops the guard. Because the lock is in the cache directory
itself, it works across processes on the same machine but not across networked filesystems
(uv emits a warning if the cache appears to live on NFS or SMB).
Refresh policies
Most operations honor a Refresh:
Refresh::None— read the cache as-is.Refresh::All(timestamp)— invalidate any entry older thantimestamp.Refresh::Packages(set, timestamp)— invalidate only the listed packages.
The --refresh and --refresh-package CLI flags map to these. The Timestamp is a wrapper
around SystemTime that survives serialization to TOML.
uv cache commands
uv cache dir(crates/uv/src/commands/cache_dir.rs) — prints the cache root.uv cache size— sums entry sizes viaRemover.uv cache prune— removes old archives and unreachable entries.uv cache clean— wipes everything.
Integration points
uv-clientwrites Simple/JSON responses intoSimple/FlatIndexbuckets and downloaded wheels intoWheels/Sdists.uv-distributionstores per-distribution metadata and built wheels. Source builds are deduplicated by content hash so that two requests for the same sdist build it only once.uv-installerconsultsArchiveto know what's already unpacked and stores newly-installed wheels into it.uv-pythoncaches interpreter query results inInterpreter.uv-gitstores checked-out repos inGit.
Entry points for modification
- Add a new bucket — extend
CacheBucketinlib.rs, give it a string and a version suffix into_str. Bump the suffix when changing the format. - Change cache layout — when changing the on-disk shape of an existing bucket, bump the version suffix to avoid mixing old and new entries.
- Add a new refresh signal — extend
Refreshand thread it through the consumers.
Key source files
| File | Purpose |
|---|---|
crates/uv-cache/src/lib.rs |
Cache, CacheBucket, CacheEntry, CacheShard, locking. |
crates/uv-cache/src/wheel.rs |
Wheel-aware cache shards. |
crates/uv-cache/src/archive.rs |
ArchiveId for content-addressed unpacks. |
crates/uv-cache/src/removal.rs |
Remover for cleanup commands. |
crates/uv-cache/src/by_timestamp.rs |
Timestamp-based invalidation. |
See also
uv-fsfor the lock primitive.uv-cache-infoforTimestampand other cache metadata helpers.uv-clientfor the HTTP read-through cache.uv-installerfor the archive-consuming side.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.