diff --git a/lib/manager/pip-compile/__fixtures__/requirementsNoHeaders.txt b/lib/manager/pip-compile/__fixtures__/requirementsNoHeaders.txt
new file mode 100644
index 0000000000000000000000000000000000000000..3fc1aa13920366fe9bd6cccb78113b741fd79fd5
--- /dev/null
+++ b/lib/manager/pip-compile/__fixtures__/requirementsNoHeaders.txt
@@ -0,0 +1,5 @@
+# simple comment
+some-package==0.3.1
+some-other-package==1.0.0
+sphinx
+not_semver==1.9
diff --git a/lib/manager/pip-compile/__fixtures__/requirementsWithExploitingArguments.txt b/lib/manager/pip-compile/__fixtures__/requirementsWithExploitingArguments.txt
new file mode 100644
index 0000000000000000000000000000000000000000..930ea670d1dfd77adc46a3f5cedb040049da904f
--- /dev/null
+++ b/lib/manager/pip-compile/__fixtures__/requirementsWithExploitingArguments.txt
@@ -0,0 +1,9 @@
+#
+# This file is autogenerated by pip-compile with python 3.9
+# To update, run:
+#
+#    pip-compile --generate-hashes --$(curl asdf) --output-file=/etc/shadow requirements.in
+#
+attrs==21.2.0 \
+    --hash=sha256:149e90d6d8ac20db7a955ad60cf0e6881a3f20d37096140088356da6c716b0b1 \
+    --hash=sha256:ef6aaac3ca6cd92904cdd0d83f629a15f18053ec84e6432106f7a4d04ae4f5fb
diff --git a/lib/manager/pip-compile/__fixtures__/requirementsWithHashes.txt b/lib/manager/pip-compile/__fixtures__/requirementsWithHashes.txt
new file mode 100644
index 0000000000000000000000000000000000000000..38ca9ec1db8b2a8800bd8e76832de02b9bb5336d
--- /dev/null
+++ b/lib/manager/pip-compile/__fixtures__/requirementsWithHashes.txt
@@ -0,0 +1,14 @@
+#
+# This file is autogenerated by pip-compile with python 3.9
+# To update, run:
+#
+#    pip-compile --allow-unsafe --generate-hashes --output-file=requirements.txt requirements.in
+#
+attrs==21.2.0 \
+    --hash=sha256:149e90d6d8ac20db7a955ad60cf0e6881a3f20d37096140088356da6c716b0b1 \
+    --hash=sha256:ef6aaac3ca6cd92904cdd0d83f629a15f18053ec84e6432106f7a4d04ae4f5fb
+
+# The following packages are considered to be unsafe in a requirements file:
+setuptools==59.2.0 \
+    --hash=sha256:157d21de9d055ab9e8ea3186d91e7f4f865e11f42deafa952d90842671fc2576 \
+    --hash=sha256:4adde3d1e1c89bde1c643c64d89cdd94cbfd8c75252ee459d4500bccb9c7d05d
diff --git a/lib/manager/pip-compile/__fixtures__/requirementsWithUnknownArguments.txt b/lib/manager/pip-compile/__fixtures__/requirementsWithUnknownArguments.txt
new file mode 100644
index 0000000000000000000000000000000000000000..a2f060d3347a1fe7941f1c130c2a2094c1ac5d6f
--- /dev/null
+++ b/lib/manager/pip-compile/__fixtures__/requirementsWithUnknownArguments.txt
@@ -0,0 +1,9 @@
+#
+# This file is autogenerated by pip-compile with python 3.9
+# To update, run:
+#
+#    pip-compile --generate-hashes --version requirements.in
+#
+attrs==21.2.0 \
+    --hash=sha256:149e90d6d8ac20db7a955ad60cf0e6881a3f20d37096140088356da6c716b0b1 \
+    --hash=sha256:ef6aaac3ca6cd92904cdd0d83f629a15f18053ec84e6432106f7a4d04ae4f5fb
diff --git a/lib/manager/pip-compile/artifacts.spec.ts b/lib/manager/pip-compile/artifacts.spec.ts
index 6b37eb0e079291307405db7dc302f4cc907bf253..094a4a1dfc2cfc6c4f20214804908e80051da617 100644
--- a/lib/manager/pip-compile/artifacts.spec.ts
+++ b/lib/manager/pip-compile/artifacts.spec.ts
@@ -2,9 +2,11 @@ import { exec as _exec } from 'child_process';
 import _fs from 'fs-extra';
 import { join } from 'upath';
 import { envMock, mockExecAll } from '../../../test/exec-util';
+import { Fixtures } from '../../../test/fixtures';
 import { git, mocked } from '../../../test/util';
 import { GlobalConfig } from '../../config/global';
 import type { RepoGlobalConfig } from '../../config/types';
+import { logger } from '../../logger';
 import * as docker from '../../util/exec/docker';
 import * as _env from '../../util/exec/env';
 import type { StatusResult } from '../../util/git/types';
@@ -160,4 +162,58 @@ describe('manager/pip-compile/artifacts', () => {
     ).not.toBeNull();
     expect(execSnapshots).toMatchSnapshot();
   });
+
+  describe('constructPipCompileCmd()', () => {
+    it('returns default cmd for garbage', () => {
+      expect(
+        pipCompile.constructPipCompileCmd(
+          Fixtures.get('requirementsNoHeaders.txt'),
+          'subdir/requirements.in',
+          'subdir/requirements.txt'
+        )
+      ).toBe('pip-compile requirements.in');
+    });
+
+    it('returns extracted common arguments (like those featured in the README)', () => {
+      expect(
+        pipCompile.constructPipCompileCmd(
+          Fixtures.get('requirementsWithHashes.txt'),
+          'subdir/requirements.in',
+          'subdir/requirements.txt'
+        )
+      ).toBe(
+        'pip-compile --allow-unsafe --generate-hashes --output-file=requirements.txt requirements.in'
+      );
+    });
+
+    it('skips unknown arguments', () => {
+      expect(
+        pipCompile.constructPipCompileCmd(
+          Fixtures.get('requirementsWithUnknownArguments.txt'),
+          'subdir/requirements.in',
+          'subdir/requirements.txt'
+        )
+      ).toBe('pip-compile --generate-hashes requirements.in');
+      expect(logger.trace).toHaveBeenCalledWith(
+        { argument: '--version' },
+        'pip-compile argument is not (yet) supported'
+      );
+    });
+
+    it('skips exploitable subcommands and files', () => {
+      expect(
+        pipCompile.constructPipCompileCmd(
+          Fixtures.get('requirementsWithExploitingArguments.txt'),
+          'subdir/requirements.in',
+          'subdir/requirements.txt'
+        )
+      ).toBe(
+        'pip-compile --generate-hashes --output-file=requirements.txt requirements.in'
+      );
+      expect(logger.warn).toHaveBeenCalledWith(
+        { argument: '--output-file=/etc/shadow' },
+        'pip-compile was previously executed with an unexpected `--output-file` filename'
+      );
+    });
+  });
 });
diff --git a/lib/manager/pip-compile/artifacts.ts b/lib/manager/pip-compile/artifacts.ts
index dd79a9acd2b47885881f7cf9efb1efbbd449038c..f2848b7b3cb81f46c87c94235edd8c77fdfe7ece 100644
--- a/lib/manager/pip-compile/artifacts.ts
+++ b/lib/manager/pip-compile/artifacts.ts
@@ -1,5 +1,5 @@
 import is from '@sindresorhus/is';
-import { quote } from 'shlex';
+import { quote, split } from 'shlex';
 import upath from 'upath';
 import { TEMPORARY_ERROR } from '../../constants/error-messages';
 import { logger } from '../../logger';
@@ -40,6 +40,47 @@ function getPipToolsConstraint(config: UpdateArtifactsConfig): string {
   return '';
 }
 
+const constraintLineRegex = regEx(
+  /^(#.*?\r?\n)+# {4}pip-compile(?<arguments>.*?)\r?\n/
+);
+
+export function constructPipCompileCmd(
+  content: string,
+  inputFileName: string,
+  outputFileName: string
+): string {
+  const headers = constraintLineRegex.exec(content);
+  const args = ['pip-compile'];
+  if (headers) {
+    logger.debug({ header: headers[0] }, 'Found pip-compile header');
+    for (const argument of split(headers.groups.arguments)) {
+      if (['--allow-unsafe', '--generate-hashes'].includes(argument)) {
+        args.push(argument);
+      } else if (argument.startsWith('--output-file=')) {
+        const file = upath.parse(outputFileName).base;
+        if (argument !== `--output-file=${file}`) {
+          // we don't trust the user-supplied output-file argument; use our value here
+          logger.warn(
+            { argument },
+            'pip-compile was previously executed with an unexpected `--output-file` filename'
+          );
+        }
+        args.push(`--output-file=${file}`);
+      } else if (argument.startsWith('--')) {
+        logger.trace(
+          { argument },
+          'pip-compile argument is not (yet) supported'
+        );
+      } else {
+        // ignore position argument (.in file)
+      }
+    }
+  }
+  args.push(upath.parse(inputFileName).base);
+
+  return args.map((argument) => quote(argument)).join(' ');
+}
+
 export async function updateArtifacts({
   packageFileName: inputFileName,
   newPackageFileContent: newInputContent,
@@ -59,7 +100,11 @@ export async function updateArtifacts({
     if (config.isLockFileMaintenance) {
       await deleteLocalFile(outputFileName);
     }
-    const cmd = `pip-compile ${quote(upath.parse(inputFileName).base)}`;
+    const cmd = constructPipCompileCmd(
+      existingOutput,
+      inputFileName,
+      outputFileName
+    );
     const tagConstraint = getPythonConstraint(config);
     const pipToolsConstraint = getPipToolsConstraint(config);
     const execOptions: ExecOptions = {
diff --git a/lib/manager/pip-compile/readme.md b/lib/manager/pip-compile/readme.md
index 42330b600641fb3c2b94f831cc11e1f54d521500..6118ab5303c161634d66a7e6ed9ba3d6f6754c35 100644
--- a/lib/manager/pip-compile/readme.md
+++ b/lib/manager/pip-compile/readme.md
@@ -40,3 +40,10 @@ To get Renovate to use another version of Python, add a contraints` rule to the
   }
 }
 ```
+
+### `pip-compile` arguments
+
+Renovate reads the `requirements.txt` file and extracts these `pip-compile` arguments:
+
+- `--generate-hashes`
+- `--allow-unsafe`