diff --git a/lib/modules/manager/types.ts b/lib/modules/manager/types.ts
index 2ce51aa306a0d93b43f764686a3913adf39bd834..7fa394d4ebaa1135728631e824bce2822281cd87 100644
--- a/lib/modules/manager/types.ts
+++ b/lib/modules/manager/types.ts
@@ -106,6 +106,7 @@ export interface LookupUpdate {
   releaseTimestamp?: any;
   newVersionAgeInDays?: number;
   registryUrl?: string;
+  libYears?: number;
 }
 
 /**
@@ -144,6 +145,7 @@ export interface PackageDependency<T = Record<string, any>>
   digestOneAndOnly?: boolean;
   fixedVersion?: string;
   currentVersion?: string;
+  currentVersionTimestamp?: string;
   lockedVersion?: string;
   propSource?: string;
   registryUrls?: string[] | null;
diff --git a/lib/workers/repository/process/extract-update.ts b/lib/workers/repository/process/extract-update.ts
index 8cc0163d84d363739240cd83199633eaab4d1bba..f2a42103ec8c5216b3f4f83d3eccbcdd5777592a 100644
--- a/lib/workers/repository/process/extract-update.ts
+++ b/lib/workers/repository/process/extract-update.ts
@@ -13,6 +13,7 @@ import { extractAllDependencies } from '../extract';
 import { generateFingerprintConfig } from '../extract/extract-fingerprint-config';
 import { branchifyUpgrades } from '../updates/branchify';
 import { fetchUpdates } from './fetch';
+import { calculateLibYears } from './libyear';
 import { sortBranches } from './sort';
 import { Vulnerabilities } from './vulnerabilities';
 import type { WriteUpdateResult } from './write';
@@ -211,6 +212,7 @@ export async function lookup(
 ): Promise<ExtractResult> {
   await fetchVulnerabilities(config, packageFiles);
   await fetchUpdates(config, packageFiles);
+  calculateLibYears(packageFiles);
   const { branches, branchList } = await branchifyUpgrades(
     config,
     packageFiles,
diff --git a/lib/workers/repository/process/libyear.spec.ts b/lib/workers/repository/process/libyear.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..e4a1f1fe24ff43b2a7d7f9295be7e1fd35afa714
--- /dev/null
+++ b/lib/workers/repository/process/libyear.spec.ts
@@ -0,0 +1,104 @@
+import { logger } from '../../../../test/util';
+import type { PackageFile } from '../../../modules/manager/types';
+import { calculateLibYears } from './libyear';
+
+describe('workers/repository/process/libyear', () => {
+  describe('calculateLibYears', () => {
+    it('returns early if no packageFiles', () => {
+      calculateLibYears(undefined);
+      expect(logger.logger.debug).not.toHaveBeenCalled();
+    });
+
+    it('calculates libYears', () => {
+      const packageFiles: Record<string, PackageFile[]> = {
+        dockerfile: [
+          {
+            packageFile: 'Dockerfile',
+            deps: [
+              {
+                depName: 'some/image',
+                currentVersion: '1.0.0',
+                updates: [{ newVersion: '2.0.0' }],
+              },
+            ],
+          },
+        ],
+        npm: [
+          {
+            packageFile: 'package.json',
+            deps: [
+              {
+                depName: 'dep1',
+                currentVersion: '0.1.0',
+                currentVersionTimestamp: '2019-07-01T00:00:00Z',
+                updates: [
+                  {
+                    newVersion: '1.0.0',
+                    releaseTimestamp: '2020-01-01T00:00:00Z',
+                  },
+                  {
+                    newVersion: '2.0.0',
+                    releaseTimestamp: '2020-07-01T00:00:00Z',
+                  },
+                  {
+                    newVersion: '3.0.0',
+                  },
+                ],
+              },
+            ],
+          },
+        ],
+        bundler: [
+          {
+            packageFile: 'Gemfile',
+            deps: [
+              {
+                depName: 'dep2',
+                currentVersion: '1.0.0',
+                currentVersionTimestamp: '2019-07-01T00:00:00Z',
+                updates: [
+                  {
+                    newVersion: '2.0.0',
+                    releaseTimestamp: '2020-01-01T00:00:00Z',
+                  },
+                ],
+              },
+              {
+                depName: 'dep3',
+                currentVersion: '1.0.0',
+                updates: [
+                  {
+                    newVersion: '2.0.0',
+                    releaseTimestamp: '2020-01-01T00:00:00Z',
+                  },
+                ],
+              },
+              {
+                depName: 'dep4',
+              },
+            ],
+          },
+        ],
+      };
+      calculateLibYears(packageFiles);
+      expect(logger.logger.debug).toHaveBeenCalledWith(
+        'No releaseTimestamp for some/image update to 2.0.0',
+      );
+      expect(logger.logger.debug).toHaveBeenCalledWith(
+        'No releaseTimestamp for dep1 update to 3.0.0',
+      );
+      expect(logger.logger.debug).toHaveBeenCalledWith(
+        {
+          managerLibYears: {
+            bundler: 0.5027322404371585,
+            dockerfile: 0,
+            npm: 1,
+          },
+          // eslint-disable-next-line no-loss-of-precision
+          totalLibYears: 1.5027322404371585,
+        },
+        'Repository libYears',
+      );
+    });
+  });
+});
diff --git a/lib/workers/repository/process/libyear.ts b/lib/workers/repository/process/libyear.ts
new file mode 100644
index 0000000000000000000000000000000000000000..f2bf607b2aa1e9cced2b368280904621a714dc54
--- /dev/null
+++ b/lib/workers/repository/process/libyear.ts
@@ -0,0 +1,59 @@
+import { DateTime } from 'luxon';
+import { logger } from '../../../logger';
+import type { PackageFile } from '../../../modules/manager/types';
+
+export function calculateLibYears(
+  packageFiles?: Record<string, PackageFile[]>,
+): void {
+  if (!packageFiles) {
+    return;
+  }
+  const managerLibYears: Record<string, number> = {};
+  for (const [manager, files] of Object.entries(packageFiles)) {
+    for (const file of files) {
+      let fileLibYears = 0;
+      for (const dep of file.deps) {
+        if (dep.updates?.length) {
+          for (const update of dep.updates) {
+            if (!update.releaseTimestamp) {
+              logger.debug(
+                `No releaseTimestamp for ${dep.depName} update to ${update.newVersion}`,
+              );
+              continue;
+            }
+            if (!dep.currentVersionTimestamp) {
+              logger.debug(`No currentVersionTimestamp for ${dep.depName}`);
+              continue;
+            }
+            // timestamps are in ISO format
+            const currentVersionDate = DateTime.fromISO(
+              dep.currentVersionTimestamp,
+            );
+            const releaseDate = DateTime.fromISO(update.releaseTimestamp);
+            const libYears = releaseDate.diff(
+              currentVersionDate,
+              'years',
+            ).years;
+            if (libYears >= 0) {
+              update.libYears = libYears;
+            }
+          }
+          // Set the highest libYears for the dep
+          const depLibYears = Math.max(
+            ...dep.updates.map((update) => update.libYears ?? 0),
+            0,
+          );
+          fileLibYears += depLibYears;
+        }
+      }
+      managerLibYears[manager] ??= 0;
+      managerLibYears[manager] += fileLibYears;
+    }
+  }
+  // Sum up the libYears for the repo
+  let totalLibYears = 0;
+  for (const libYears of Object.values(managerLibYears)) {
+    totalLibYears += libYears;
+  }
+  logger.debug({ managerLibYears, totalLibYears }, 'Repository libYears');
+}