diff --git a/lib/modules/manager/pip-compile/extract.spec.ts b/lib/modules/manager/pip-compile/extract.spec.ts
index 786fc48a1a9007cb57ba0b762ef516f9b9184ec0..9e9f55720f089a15cad17237729ff95985450ca0 100644
--- a/lib/modules/manager/pip-compile/extract.spec.ts
+++ b/lib/modules/manager/pip-compile/extract.spec.ts
@@ -159,6 +159,79 @@ describe('modules/manager/pip-compile/extract', () => {
     expect(packageFiles).toBeNull();
   });
 
+  it('return sorted package files', async () => {
+    fs.readLocalFile.mockResolvedValueOnce(
+      getSimpleRequirementsFile('pip-compile --output-file=4.txt 3.in', [
+        'foo==1.0.1',
+      ]),
+    );
+    fs.readLocalFile.mockResolvedValueOnce('-r 2.txt\nfoo');
+    fs.readLocalFile.mockResolvedValueOnce(
+      getSimpleRequirementsFile('pip-compile --output-file=2.txt 1.in', [
+        'foo==1.0.1',
+      ]),
+    );
+    fs.readLocalFile.mockResolvedValueOnce('foo');
+
+    const lockFiles = ['4.txt', '2.txt'];
+    const packageFiles = await extractAllPackageFiles({}, lockFiles);
+    expect(packageFiles).toBeDefined();
+    expect(packageFiles?.map((p) => p.packageFile)).toEqual(['1.in', '3.in']);
+    expect(packageFiles?.map((p) => p.lockFiles!.pop())).toEqual([
+      '2.txt',
+      '4.txt',
+    ]);
+  });
+
+  it('return sorted package files with constraint in file', async () => {
+    fs.readLocalFile.mockResolvedValueOnce(
+      getSimpleRequirementsFile('pip-compile --output-file=4.txt 3.in', [
+        'foo==1.0.1',
+      ]),
+    );
+    fs.readLocalFile.mockResolvedValueOnce('-c 2.txt\nfoo');
+    fs.readLocalFile.mockResolvedValueOnce(
+      getSimpleRequirementsFile('pip-compile --output-file=2.txt 1.in', [
+        'foo==1.0.1',
+      ]),
+    );
+    fs.readLocalFile.mockResolvedValueOnce('foo');
+
+    const lockFiles = ['4.txt', '2.txt'];
+    const packageFiles = await extractAllPackageFiles({}, lockFiles);
+    expect(packageFiles).toBeDefined();
+    expect(packageFiles?.map((p) => p.packageFile)).toEqual(['1.in', '3.in']);
+    expect(packageFiles?.map((p) => p.lockFiles!.pop())).toEqual([
+      '2.txt',
+      '4.txt',
+    ]);
+  });
+
+  it('return sorted package files with constraint in command', async () => {
+    fs.readLocalFile.mockResolvedValueOnce(
+      getSimpleRequirementsFile(
+        'pip-compile --constraint=2.txt --output-file=4.txt 3.in',
+        ['foo==1.0.1'],
+      ),
+    );
+    fs.readLocalFile.mockResolvedValueOnce('foo');
+    fs.readLocalFile.mockResolvedValueOnce(
+      getSimpleRequirementsFile('pip-compile --output-file=2.txt 1.in', [
+        'foo==1.0.1',
+      ]),
+    );
+    fs.readLocalFile.mockResolvedValueOnce('foo');
+
+    const lockFiles = ['4.txt', '2.txt'];
+    const packageFiles = await extractAllPackageFiles({}, lockFiles);
+    expect(packageFiles).toBeDefined();
+    expect(packageFiles?.map((p) => p.packageFile)).toEqual(['1.in', '3.in']);
+    expect(packageFiles?.map((p) => p.lockFiles!.pop())).toEqual([
+      '2.txt',
+      '4.txt',
+    ]);
+  });
+
   it('adds lockedVersion to deps in package file', async () => {
     fs.readLocalFile.mockResolvedValueOnce(
       getSimpleRequirementsFile(
diff --git a/lib/modules/manager/pip-compile/extract.ts b/lib/modules/manager/pip-compile/extract.ts
index 72dc9c40c1b24e96e094497bba8871c975e69e46..40296061223521a157de19782ec68ed93cd90977 100644
--- a/lib/modules/manager/pip-compile/extract.ts
+++ b/lib/modules/manager/pip-compile/extract.ts
@@ -1,3 +1,4 @@
+import { Graph } from 'graph-data-structure';
 import { logger } from '../../../logger';
 import { readLocalFile } from '../../../util/fs';
 import { normalizeDepName } from '../../datasource/pypi/common';
@@ -80,8 +81,6 @@ export async function extractAllPackageFiles(
     }
     lockFileArgs.set(fileMatch, compileArgs);
     for (const constraint in compileArgs.constraintsFiles) {
-      // TODO(not7cd): handle constraints
-      /* istanbul ignore next */
       depsBetweenFiles.push({
         sourceFile: constraint,
         outputFile: fileMatch,
@@ -130,6 +129,24 @@ export async function extractAllPackageFiles(
         config,
       );
       if (packageFileContent) {
+        if (packageFileContent.managerData?.requirementsFiles) {
+          for (const file of packageFileContent.managerData.requirementsFiles) {
+            depsBetweenFiles.push({
+              sourceFile: file,
+              outputFile: packageFile,
+              type: 'requirement',
+            });
+          }
+        }
+        if (packageFileContent.managerData?.constraintsFiles) {
+          for (const file of packageFileContent.managerData.constraintsFiles) {
+            depsBetweenFiles.push({
+              sourceFile: file,
+              outputFile: packageFile,
+              type: 'requirement',
+            });
+          }
+        }
         for (const dep of packageFileContent.deps) {
           const lockedVersion = lockedDeps?.find(
             (lockedDep) =>
@@ -158,13 +175,38 @@ export async function extractAllPackageFiles(
       }
     }
   }
-  // TODO(not7cd): sort by requirement layering (-r -c within .in files)
   if (packageFiles.size === 0) {
     return null;
   }
+  const result: PackageFile[] = [];
+  const graph: ReturnType<typeof Graph> = Graph();
+  depsBetweenFiles.forEach(({ sourceFile, outputFile }) => {
+    graph.addEdge(sourceFile, outputFile);
+  });
+  const sorted = graph.topologicalSort();
+  for (const file of sorted) {
+    if (packageFiles.has(file)) {
+      const packageFile = packageFiles.get(file)!;
+      const sortedLockFiles = [];
+      // TODO(not7cd): this needs better test case
+      for (const lockFile of packageFile.lockFiles!) {
+        if (sorted.includes(lockFile)) {
+          sortedLockFiles.push(lockFile);
+        }
+      }
+      packageFile.lockFiles = sortedLockFiles;
+      result.push(packageFile);
+    }
+  }
+  // istanbul ignore if: should never happen
+  if (result.length !== packageFiles.size) {
+    throw new Error(
+      'pip-compile: topological sort failed to include all package files',
+    );
+  }
   logger.debug(
     'pip-compile: dependency graph:\n' +
       generateMermaidGraph(depsBetweenFiles, lockFileArgs),
   );
-  return Array.from(packageFiles.values());
+  return result;
 }