diff --git a/__tests__/restore.test.ts b/__tests__/restore.test.ts
index c96a2d6..59077ba 100644
--- a/__tests__/restore.test.ts
+++ b/__tests__/restore.test.ts
@@ -401,3 +401,57 @@ test("restore with cache found for restore key", async () => {
     );
     expect(failedMock).toHaveBeenCalledTimes(0);
 });
+
+test("restore skipped with save-only", async () => {
+    const key = "node-test";
+    const restoreKey = "node-";
+    testUtils.setInputs({
+        path: "node_modules",
+        key,
+        restoreKeys: [restoreKey],
+        saveOnly: "true"
+    });
+
+    const infoMock = jest.spyOn(core, "info");
+    const failedMock = jest.spyOn(core, "setFailed");
+    const stateMock = jest.spyOn(core, "saveState");
+
+    const cacheEntry: ArtifactCacheEntry = {
+        cacheKey: restoreKey,
+        scope: "refs/heads/master",
+        archiveLocation: "www.actionscache.test/download"
+    };
+    const getCacheMock = jest.spyOn(cacheHttpClient, "getCacheEntry");
+    getCacheMock.mockImplementation(() => {
+        return Promise.resolve(cacheEntry);
+    });
+    const tempPath = "/foo/bar";
+
+    const createTempDirectoryMock = jest.spyOn(
+        actionUtils,
+        "createTempDirectory"
+    );
+    createTempDirectoryMock.mockImplementation(() => {
+        return Promise.resolve(tempPath);
+    });
+
+    const setCacheStateMock = jest.spyOn(actionUtils, "setCacheState");
+    const downloadCacheMock = jest.spyOn(cacheHttpClient, "downloadCache");
+    const setCacheHitOutputMock = jest.spyOn(actionUtils, "setCacheHitOutput");
+
+    await run();
+
+    expect(stateMock).toHaveBeenCalledWith("CACHE_KEY", key);
+    expect(getCacheMock).toHaveBeenCalledWith([key, restoreKey]);
+    expect(setCacheStateMock).toHaveBeenCalledWith(cacheEntry);
+    expect(createTempDirectoryMock).toHaveBeenCalledTimes(0);
+    expect(downloadCacheMock).toHaveBeenCalledTimes(0);
+
+    expect(setCacheHitOutputMock).toHaveBeenCalledTimes(1);
+    expect(setCacheHitOutputMock).toHaveBeenCalledWith(false);
+
+    expect(infoMock).toHaveBeenCalledWith(
+        "Cache action configured for save-only, skipping restore step."
+    );
+    expect(failedMock).toHaveBeenCalledTimes(0);
+});
diff --git a/__tests__/save.test.ts b/__tests__/save.test.ts
index 75938f1..2491434 100644
--- a/__tests__/save.test.ts
+++ b/__tests__/save.test.ts
@@ -414,7 +414,7 @@ test("save skipped with restore only", async () => {
     await run();
 
     expect(infoMock).toHaveBeenCalledWith(
-        "Cache action configured for restore-only, skipping save step"
+        "Cache action configured for restore-only, skipping save step."
     );
 
     expect(reserveCacheMock).toHaveBeenCalledTimes(0);
diff --git a/action.yml b/action.yml
index 7af781e..bf73ef6 100644
--- a/action.yml
+++ b/action.yml
@@ -14,6 +14,9 @@ inputs:
   restore-only:
     description: 'Disables saving a new cache entry when true'
     required: false
+  save-only:
+    description: 'Disables downloading and restoring a new cache entry when true'
+    required: false
 outputs:
   cache-hit:
     description: 'A boolean value to indicate an exact match was found for the primary key'
diff --git a/src/constants.ts b/src/constants.ts
index 9c41c59..60871a9 100644
--- a/src/constants.ts
+++ b/src/constants.ts
@@ -2,7 +2,8 @@ export enum Inputs {
     Key = "key",
     Path = "path",
     RestoreKeys = "restore-keys",
-    RestoreOnly = "restore-only"
+    RestoreOnly = "restore-only",
+    SaveOnly = "save-only"
 }
 
 export enum Outputs {
diff --git a/src/restore.ts b/src/restore.ts
index 4911e7e..b200c6c 100644
--- a/src/restore.ts
+++ b/src/restore.ts
@@ -67,15 +67,28 @@ async function run(): Promise<void> {
                 return;
             }
 
+            const isExactKeyMatch = utils.isExactKeyMatch(
+                primaryKey,
+                cacheEntry
+            );
+
+            // Store the cache result
+            utils.setCacheState(cacheEntry);
+
+            if (core.getInput(Inputs.SaveOnly) === "true") {
+                core.info(
+                    "Cache action configured for save-only, skipping restore step."
+                );
+                utils.setCacheHitOutput(isExactKeyMatch);
+                return;
+            }
+
             const archivePath = path.join(
                 await utils.createTempDirectory(),
                 "cache.tgz"
             );
             core.debug(`Archive Path: ${archivePath}`);
 
-            // Store the cache result
-            utils.setCacheState(cacheEntry);
-
             // Download the cache from the cache entry
             await cacheHttpClient.downloadCache(
                 cacheEntry.archiveLocation,
@@ -91,10 +104,6 @@ async function run(): Promise<void> {
 
             await extractTar(archivePath, cachePath);
 
-            const isExactKeyMatch = utils.isExactKeyMatch(
-                primaryKey,
-                cacheEntry
-            );
             utils.setCacheHitOutput(isExactKeyMatch);
 
             core.info(
diff --git a/src/save.ts b/src/save.ts
index cf4facf..bac9f00 100644
--- a/src/save.ts
+++ b/src/save.ts
@@ -20,7 +20,7 @@ async function run(): Promise<void> {
 
         if (core.getInput(Inputs.RestoreOnly) === "true") {
             core.info(
-                "Cache action configured for restore-only, skipping save step"
+                "Cache action configured for restore-only, skipping save step."
             );
             return;
         }
diff --git a/src/utils/testUtils.ts b/src/utils/testUtils.ts
index b1d20d0..115fe37 100644
--- a/src/utils/testUtils.ts
+++ b/src/utils/testUtils.ts
@@ -13,6 +13,8 @@ interface CacheInput {
     path: string;
     key: string;
     restoreKeys?: string[];
+    restoreOnly?: string;
+    saveOnly?: string;
 }
 
 export function setInputs(input: CacheInput): void {
@@ -20,10 +22,14 @@ export function setInputs(input: CacheInput): void {
     setInput(Inputs.Key, input.key);
     input.restoreKeys &&
         setInput(Inputs.RestoreKeys, input.restoreKeys.join("\n"));
+    input.restoreOnly && setInput(Inputs.RestoreOnly, input.restoreOnly);
+    input.saveOnly && setInput(Inputs.SaveOnly, input.saveOnly);
 }
 
 export function clearInputs(): void {
     delete process.env[getInputName(Inputs.Path)];
     delete process.env[getInputName(Inputs.Key)];
     delete process.env[getInputName(Inputs.RestoreKeys)];
+    delete process.env[getInputName(Inputs.RestoreOnly)];
+    delete process.env[getInputName(Inputs.SaveOnly)];
 }