diff --git a/docs/usage/configuration-options.md b/docs/usage/configuration-options.md
index 9bb09058e75cc4f491bd9742b583996c92cda6be..89b984479b673916299a8a2b8b5bb6e6eca246a0 100644
--- a/docs/usage/configuration-options.md
+++ b/docs/usage/configuration-options.md
@@ -2168,6 +2168,7 @@ Table with options:
 | `gomodTidyE`             | Run `go mod tidy -e` after Go module updates.                                                                                                              |
 | `gomodUpdateImportPaths` | Update source import paths on major module updates, using [mod](https://github.com/marwan-at-work/mod).                                                    |
 | `npmDedupe`              | Run `npm dedupe` after `package-lock.json` updates.                                                                                                        |
+| `pnpmDedupe`             | Run `pnpm dedupe` after `pnpm-lock.yaml` updates.                                                                                                          |
 | `yarnDedupeFewer`        | Run `yarn-deduplicate --strategy fewer` after `yarn.lock` updates.                                                                                         |
 | `yarnDedupeHighest`      | Run `yarn-deduplicate --strategy highest` (`yarn dedupe --strategy highest` for Yarn >=2.2.0) after `yarn.lock` updates.                                   |
 
diff --git a/lib/config/options/index.ts b/lib/config/options/index.ts
index ec1f31ecd569bae7ddeb1e6cd579f2c497fb26f9..9d8f7c315c4fc5048f1944c996b28fce09eb79de 100644
--- a/lib/config/options/index.ts
+++ b/lib/config/options/index.ts
@@ -1996,6 +1996,7 @@ const options: RenovateOptions[] = [
       'gomodTidy1.17',
       'gomodTidyE',
       'npmDedupe',
+      'pnpmDedupe',
       'yarnDedupeFewer',
       'yarnDedupeHighest',
     ],
diff --git a/lib/modules/manager/npm/post-update/pnpm.spec.ts b/lib/modules/manager/npm/post-update/pnpm.spec.ts
index cacdcbc3a7f1fdbf902b3841b0d40926b36b9073..8f5091329b7dfe3819996877e10f778a529d4c45 100644
--- a/lib/modules/manager/npm/post-update/pnpm.spec.ts
+++ b/lib/modules/manager/npm/post-update/pnpm.spec.ts
@@ -69,6 +69,27 @@ describe('modules/manager/npm/post-update/pnpm', () => {
     expect(execSnapshots).toMatchSnapshot();
   });
 
+  it('performs dedupe', async () => {
+    const execSnapshots = mockExecAll();
+    fs.readLocalFile.mockResolvedValue('package-lock-contents');
+    const postUpdateOptions = ['pnpmDedupe'];
+    const res = await pnpmHelper.generateLockFile(
+      'some-dir',
+      {},
+      { ...config, postUpdateOptions }
+    );
+    expect(fs.readLocalFile).toHaveBeenCalledTimes(1);
+    expect(res.lockFile).toBe('package-lock-contents');
+    expect(execSnapshots).toMatchObject([
+      {
+        cmd: 'pnpm install --recursive --lockfile-only --ignore-scripts --ignore-pnpmfile',
+      },
+      {
+        cmd: 'pnpm dedupe',
+      },
+    ]);
+  });
+
   it('uses the new version if packageManager is updated', async () => {
     const execSnapshots = mockExecAll();
     fs.readLocalFile.mockResolvedValue('package-lock-contents');
diff --git a/lib/modules/manager/npm/post-update/pnpm.ts b/lib/modules/manager/npm/post-update/pnpm.ts
index 4cb2e7d19bff9ed9214c67d1411b66faf1aabec3..8f0845c7054e70b6d046558da1888a32a43eb01b 100644
--- a/lib/modules/manager/npm/post-update/pnpm.ts
+++ b/lib/modules/manager/npm/post-update/pnpm.ts
@@ -53,6 +53,8 @@ export async function generateLockFile(
       extraEnv.NPM_AUTH = env.NPM_AUTH;
       extraEnv.NPM_EMAIL = env.NPM_EMAIL;
     }
+    const commands: string[] = [];
+
     cmd = 'pnpm';
     let args = 'install --recursive --lockfile-only';
     if (!GlobalConfig.get('allowScripts') || config.ignoreScripts) {
@@ -60,6 +62,13 @@ export async function generateLockFile(
       args += ' --ignore-pnpmfile';
     }
     logger.trace({ cmd, args }, 'pnpm command');
+    commands.push(`${cmd} ${args}`);
+
+    // postUpdateOptions
+    if (config.postUpdateOptions?.includes('pnpmDedupe')) {
+      logger.debug('Performing pnpm dedupe');
+      commands.push('pnpm dedupe');
+    }
 
     if (upgrades.find((upgrade) => upgrade.isLockFileMaintenance)) {
       logger.debug(
@@ -75,7 +84,7 @@ export async function generateLockFile(
       }
     }
 
-    await exec(`${cmd} ${args}`, execOptions);
+    await exec(commands, execOptions);
     lockFile = await readLocalFile(lockFileName, 'utf8');
   } catch (err) /* istanbul ignore next */ {
     if (err.message === TEMPORARY_ERROR) {