diff --git a/__tests__/save.test.ts b/__tests__/save.test.ts
index 30178a2..1b4376b 100644
--- a/__tests__/save.test.ts
+++ b/__tests__/save.test.ts
@@ -142,6 +142,38 @@ test("save with exact match returns early", async () => {
     expect(failedMock).toHaveBeenCalledTimes(0);
 });
 
+test("save with force-update", async () => {
+    const failedMock = jest.spyOn(core, "setFailed");
+
+    const primaryKey = "Linux-node-bb828da54c148048dd17899ba9fda624811cfb43";
+    const savedCacheKey = primaryKey;
+
+    jest.spyOn(core, "getState")
+        // Cache Entry State
+        .mockImplementationOnce(() => {
+            return savedCacheKey;
+        })
+        // Cache Key State
+        .mockImplementationOnce(() => {
+            return primaryKey;
+        });
+
+    testUtils.setInput(Inputs.ForceUpdate, "true");
+    testUtils.setInput(Inputs.Path, "node_modules");
+
+    const cacheId = 4;
+    const saveCacheMock = jest
+        .spyOn(cache, "saveCache")
+        .mockImplementationOnce(() => {
+            return Promise.resolve(cacheId);
+        });
+
+    await run();
+
+    expect(saveCacheMock).toHaveBeenCalledTimes(1);
+    expect(failedMock).toHaveBeenCalledTimes(0);
+});
+
 test("save with missing input outputs warning", async () => {
     const logWarningMock = jest.spyOn(actionUtils, "logWarning");
     const failedMock = jest.spyOn(core, "setFailed");
diff --git a/src/constants.ts b/src/constants.ts
index 133f47d..fc729f2 100644
--- a/src/constants.ts
+++ b/src/constants.ts
@@ -1,4 +1,5 @@
 export enum Inputs {
+    ForceUpdate = "force-update",
     Key = "key",
     Path = "path",
     RestoreKeys = "restore-keys",
diff --git a/src/save.ts b/src/save.ts
index fc0eb73..e0063c6 100644
--- a/src/save.ts
+++ b/src/save.ts
@@ -27,8 +27,6 @@ async function run(): Promise<void> {
             return;
         }
 
-        const state = utils.getCacheState();
-
         // Inputs are re-evaluted before the post action, so we want the original key used for restore
         const primaryKey = core.getState(State.CachePrimaryKey);
         if (!primaryKey) {
@@ -36,7 +34,9 @@ async function run(): Promise<void> {
             return;
         }
 
-        if (utils.isExactKeyMatch(primaryKey, state)) {
+        const forceUpdate = core.getInput(Inputs.ForceUpdate) === "true";
+        const state = utils.getCacheState();
+        if (utils.isExactKeyMatch(primaryKey, state) && !forceUpdate) {
             core.info(
                 `Cache hit occurred on the primary key ${primaryKey}, not saving cache.`
             );
diff --git a/src/utils/testUtils.ts b/src/utils/testUtils.ts
index 9e2134f..3cfb82f 100644
--- a/src/utils/testUtils.ts
+++ b/src/utils/testUtils.ts
@@ -23,6 +23,7 @@ export function setInputs(input: CacheInput): void {
 }
 
 export function clearInputs(): void {
+    delete process.env[getInputName(Inputs.ForceUpdate)];
     delete process.env[getInputName(Inputs.Path)];
     delete process.env[getInputName(Inputs.Key)];
     delete process.env[getInputName(Inputs.RestoreKeys)];