diff --git a/README.md b/README.md
index 3be400c..709c8ef 100644
--- a/README.md
+++ b/README.md
@@ -166,6 +166,26 @@ It defaults to `setup-uv-cache` in the `TMP` dir, `D:\a\_temp\uv-tool-dir` on Wi
     cache-local-path: "/path/to/cache"
 ```
 
+### Disable cache pruning
+
+By default, the uv cache is pruned after every run, removing pre-built wheels, but retaining any
+wheels that were built from source. On GitHub-hosted runners, it's typically faster to omit those
+pre-built wheels from the cache (and instead re-download them from the registry on each run).
+However, on self-hosted or local runners, preserving the cache may be more efficient. See
+the[documentation](https://docs.astral.sh/uv/concepts/cache/#caching-in-continuous-integration) for
+more.
+
+If you want to persist the entire cache across runs, disable cache pruning with the `prune-cache`
+input.
+
+```yaml
+- name: Don't prune the cache before saving it
+  uses: astral-sh/setup-uv@v3
+  with:
+    enable-cache: true
+    prune-cache: false
+```
+
 ### GitHub authentication token
 
 This action uses the GitHub API to fetch the uv release artifacts. To avoid hitting the GitHub API
diff --git a/action.yml b/action.yml
index 8cbe5b3..bcb05f9 100644
--- a/action.yml
+++ b/action.yml
@@ -29,6 +29,9 @@ inputs:
   cache-local-path:
     description: "Local path to store the cache."
     default: ""
+  prune-cache:
+    description: "Prune cache before saving."
+    default: true
   tool-dir:
     description: "Custom path to set UV_TOOL_DIR to."
     required: false
diff --git a/dist/save-cache/index.js b/dist/save-cache/index.js
index 2619914..487844d 100644
--- a/dist/save-cache/index.js
+++ b/dist/save-cache/index.js
@@ -82645,7 +82645,9 @@ function saveCache() {
             core.info(`Cache hit occurred on key ${cacheKey}, not saving cache.`);
             return;
         }
-        yield pruneCache();
+        if (inputs_1.pruneCache) {
+            yield pruneCache();
+        }
         core.info(`Saving cache path: ${inputs_1.cacheLocalPath}`);
         yield cache.saveCache([inputs_1.cacheLocalPath], cacheKey);
         core.info(`cache saved with the key: ${cacheKey}`);
@@ -82698,7 +82700,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
     return (mod && mod.__esModule) ? mod : { "default": mod };
 };
 Object.defineProperty(exports, "__esModule", ({ value: true }));
-exports.githubToken = exports.toolDir = exports.toolBinDir = exports.cacheDependencyGlob = exports.cacheLocalPath = exports.cacheSuffix = exports.enableCache = exports.checkSum = exports.version = void 0;
+exports.githubToken = exports.toolDir = exports.toolBinDir = exports.pruneCache = exports.cacheDependencyGlob = exports.cacheLocalPath = exports.cacheSuffix = exports.enableCache = exports.checkSum = exports.version = void 0;
 const core = __importStar(__nccwpck_require__(7484));
 const node_path_1 = __importDefault(__nccwpck_require__(6760));
 exports.version = core.getInput("version");
@@ -82707,6 +82709,7 @@ exports.enableCache = core.getInput("enable-cache") === "true";
 exports.cacheSuffix = core.getInput("cache-suffix") || "";
 exports.cacheLocalPath = getCacheLocalPath();
 exports.cacheDependencyGlob = core.getInput("cache-dependency-glob");
+exports.pruneCache = core.getInput("prune-cache") === "true";
 exports.toolBinDir = getToolBinDir();
 exports.toolDir = getToolDir();
 exports.githubToken = core.getInput("github-token");
diff --git a/dist/setup/index.js b/dist/setup/index.js
index c3162ab..7f33562 100644
--- a/dist/setup/index.js
+++ b/dist/setup/index.js
@@ -90127,7 +90127,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
     return (mod && mod.__esModule) ? mod : { "default": mod };
 };
 Object.defineProperty(exports, "__esModule", ({ value: true }));
-exports.githubToken = exports.toolDir = exports.toolBinDir = exports.cacheDependencyGlob = exports.cacheLocalPath = exports.cacheSuffix = exports.enableCache = exports.checkSum = exports.version = void 0;
+exports.githubToken = exports.toolDir = exports.toolBinDir = exports.pruneCache = exports.cacheDependencyGlob = exports.cacheLocalPath = exports.cacheSuffix = exports.enableCache = exports.checkSum = exports.version = void 0;
 const core = __importStar(__nccwpck_require__(7484));
 const node_path_1 = __importDefault(__nccwpck_require__(6760));
 exports.version = core.getInput("version");
@@ -90136,6 +90136,7 @@ exports.enableCache = core.getInput("enable-cache") === "true";
 exports.cacheSuffix = core.getInput("cache-suffix") || "";
 exports.cacheLocalPath = getCacheLocalPath();
 exports.cacheDependencyGlob = core.getInput("cache-dependency-glob");
+exports.pruneCache = core.getInput("prune-cache") === "true";
 exports.toolBinDir = getToolBinDir();
 exports.toolDir = getToolDir();
 exports.githubToken = core.getInput("github-token");
diff --git a/src/save-cache.ts b/src/save-cache.ts
index 3d9558b..173c4ba 100644
--- a/src/save-cache.ts
+++ b/src/save-cache.ts
@@ -5,7 +5,11 @@ import {
   STATE_CACHE_MATCHED_KEY,
   STATE_CACHE_KEY,
 } from "./cache/restore-cache";
-import { cacheLocalPath, enableCache } from "./utils/inputs";
+import {
+  cacheLocalPath,
+  enableCache,
+  pruneCache as shouldPruneCache,
+} from "./utils/inputs";
 
 export async function run(): Promise<void> {
   try {
@@ -32,7 +36,9 @@ async function saveCache(): Promise<void> {
     return;
   }
 
-  await pruneCache();
+  if (shouldPruneCache) {
+    await pruneCache();
+  }
 
   core.info(`Saving cache path: ${cacheLocalPath}`);
   await cache.saveCache([cacheLocalPath], cacheKey);
diff --git a/src/utils/inputs.ts b/src/utils/inputs.ts
index cdad291..f010106 100644
--- a/src/utils/inputs.ts
+++ b/src/utils/inputs.ts
@@ -7,6 +7,7 @@ export const enableCache = core.getInput("enable-cache") === "true";
 export const cacheSuffix = core.getInput("cache-suffix") || "";
 export const cacheLocalPath = getCacheLocalPath();
 export const cacheDependencyGlob = core.getInput("cache-dependency-glob");
+export const pruneCache = core.getInput("prune-cache") === "true";
 export const toolBinDir = getToolBinDir();
 export const toolDir = getToolDir();
 export const githubToken = core.getInput("github-token");