diff --git a/lib/modules/datasource/rubygems/__snapshots__/index.spec.ts.snap b/lib/modules/datasource/rubygems/__snapshots__/index.spec.ts.snap
index 523f011b8492076ddd5ef2ca1def923ad842c9bd..7405c450feeec860a423f1d4147b4c9d6fdf9537 100644
--- a/lib/modules/datasource/rubygems/__snapshots__/index.spec.ts.snap
+++ b/lib/modules/datasource/rubygems/__snapshots__/index.spec.ts.snap
@@ -1025,20 +1025,6 @@ exports[`modules/datasource/rubygems/index getReleases returns a dep for GitHub
 }
 `;
 
-exports[`modules/datasource/rubygems/index getReleases returns a dep for rubygems.org package hit 1`] = `
-{
-  "registryUrl": "https://rubygems.org",
-  "releases": [
-    {
-      "version": "0.1.0",
-    },
-    {
-      "version": "0.1.1",
-    },
-  ],
-}
-`;
-
 exports[`modules/datasource/rubygems/index getReleases uses multiple source urls 1`] = `
 {
   "changelogUrl": "https://www.railschangelog.com/",
@@ -2406,20 +2392,6 @@ exports[`modules/datasource/rubygems/index getReleases uses multiple source urls
 }
 `;
 
-exports[`modules/datasource/rubygems/index getReleases uses rubygems.org if no registry urls were provided 1`] = `
-{
-  "registryUrl": "https://rubygems.org",
-  "releases": [
-    {
-      "version": "0.1.0",
-    },
-    {
-      "version": "0.1.1",
-    },
-  ],
-}
-`;
-
 exports[`modules/datasource/rubygems/index getReleases works with real data 1`] = `
 {
   "changelogUrl": "https://www.railschangelog.com/",
diff --git a/lib/modules/datasource/rubygems/index.spec.ts b/lib/modules/datasource/rubygems/index.spec.ts
index 475e55ab7143f94cedde0e4dcacd9f8b07cb494a..81fd7de90a94c6bab9761f9d59f95bed457c16d5 100644
--- a/lib/modules/datasource/rubygems/index.spec.ts
+++ b/lib/modules/datasource/rubygems/index.spec.ts
@@ -68,66 +68,39 @@ describe('modules/datasource/rubygems/index', () => {
       httpMock
         .scope('https://rubygems.org')
         .get('/versions')
-        .reply(200, rubygemsOrgVersions);
+        .reply(200, rubygemsOrgVersions)
+        .get('/api/v1/gems/1pass.json')
+        .reply(200, { name: '1pass' })
+        .get('/api/v1/versions/1pass.json')
+        .reply(200, [
+          { number: '0.1.0', created_at: '2020-01-01' },
+          { number: '0.1.1', created_at: '2021-01-01' },
+        ]);
+
       const res = await getPkgReleases({
         versioning: rubyVersioning.id,
         datasource: RubyGemsDatasource.id,
         packageName: '1pass',
         registryUrls: [],
       });
-      expect(res).not.toBeNull();
-      expect(res?.releases).toHaveLength(2);
-      expect(res).toMatchSnapshot();
-      expect(
-        res?.releases.find((release) => release.version === '0.1.1')
-      ).toBeDefined();
-      expect(
-        res?.releases.find((release) => release.version === '0.1.2')
-      ).toBeUndefined();
-    });
 
-    it('returns a dep for a package hit on an arbitrary registry that only supports old format endpoints', async () => {
-      const contribsysComVersions = `
-        created_at: 2022-06-15T17:10:25+00:00
-        ---
-        sidekiq-ent 0.7.10,1.0.0,1.0.1,1.2.4,2.0.0,2.1.2 4c0f62a49b15b4775b7fb6824ec34d45
-      `;
-      httpMock
-        .scope('https://enterprise.contribsys.com')
-        .get('/versions')
-        .reply(200, contribsysComVersions);
-      const res = await getPkgReleases({
-        versioning: rubyVersioning.id,
-        datasource: RubyGemsDatasource.id,
-        packageName: 'sidekiq-ent',
-        registryUrls: ['https://enterprise.contribsys.com'],
-      });
-      expect(res).not.toBeNull();
-      expect(res?.releases).toHaveLength(6);
       expect(res).toMatchObject({
-        registryUrl: 'https://enterprise.contribsys.com',
-        releases: expect.arrayContaining([
-          {
-            version: '0.7.10',
-          },
-          {
-            version: '1.0.0',
-          },
-        ]),
+        releases: [{ version: '0.1.0' }, { version: '0.1.1' }],
       });
-      expect(
-        res?.releases.find((release) => release.version === '2.1.2')
-      ).toBeDefined();
-      expect(
-        res?.releases.find((release) => release.version === '2.1.3')
-      ).toBeUndefined();
     });
 
     it('uses rubygems.org if no registry urls were provided', async () => {
       httpMock
         .scope('https://rubygems.org')
         .get('/versions')
-        .reply(200, rubygemsOrgVersions);
+        .reply(200, rubygemsOrgVersions)
+        .get('/api/v1/gems/1pass.json')
+        .reply(200, { name: '1pass' })
+        .get('/api/v1/versions/1pass.json')
+        .reply(200, [
+          { number: '0.1.0', created_at: '2020-01-01' },
+          { number: '0.1.1', created_at: '2021-01-01' },
+        ]);
 
       expect(
         await getPkgReleases({
@@ -144,9 +117,10 @@ describe('modules/datasource/rubygems/index', () => {
         packageName: '1pass',
         registryUrls: [],
       });
-      expect(res).not.toBeNull();
-      expect(res?.releases).toHaveLength(2);
-      expect(res).toMatchSnapshot();
+
+      expect(res).toMatchObject({
+        releases: [{ version: '0.1.0' }, { version: '0.1.1' }],
+      });
     });
 
     it('works with real data', async () => {
diff --git a/lib/modules/datasource/rubygems/index.ts b/lib/modules/datasource/rubygems/index.ts
index 8efb93ddb6847116be8c229884768a55b057d835..580f487b59d80ac2207e72248cc95aa5796521c9 100644
--- a/lib/modules/datasource/rubygems/index.ts
+++ b/lib/modules/datasource/rubygems/index.ts
@@ -7,16 +7,20 @@ import * as rubyVersioning from '../../versioning/ruby';
 import { Datasource } from '../datasource';
 import type { GetReleasesConfig, Release, ReleaseResult } from '../types';
 import { RubygemsHttp } from './http';
+import { MetadataCache } from './metadata-cache';
 import { GemMetadata, GemVersions, MarshalledVersionInfo } from './schema';
 import { VersionsEndpointCache } from './versions-endpoint-cache';
 
 export class RubyGemsDatasource extends Datasource {
   static readonly id = 'rubygems';
 
+  private metadataCache: MetadataCache;
+
   constructor() {
     super(RubyGemsDatasource.id);
     this.http = new RubygemsHttp(RubyGemsDatasource.id);
     this.versionsEndpointCache = new VersionsEndpointCache(this.http);
+    this.metadataCache = new MetadataCache(this.http);
   }
 
   override readonly defaultRegistryUrls = ['https://rubygems.org'];
@@ -27,13 +31,6 @@ export class RubyGemsDatasource extends Datasource {
 
   private readonly versionsEndpointCache: VersionsEndpointCache;
 
-  @cache({
-    namespace: `datasource-${RubyGemsDatasource.id}`,
-    key: ({ registryUrl, packageName }: GetReleasesConfig) =>
-      // TODO: types (#7154)
-      /* eslint-disable @typescript-eslint/restrict-template-expressions */
-      `${registryUrl}/${packageName}`,
-  })
   async getReleases({
     packageName,
     registryUrl,
@@ -51,7 +48,12 @@ export class RubyGemsDatasource extends Datasource {
 
       if (cachedVersions.type === 'success') {
         const { versions } = cachedVersions;
-        return { releases: versions.map((version) => ({ version })) };
+        const result = await this.metadataCache.getRelease(
+          registryUrl,
+          packageName,
+          versions
+        );
+        return result;
       }
 
       const registryHostname = parseUrl(registryUrl)?.hostname;
@@ -87,6 +89,13 @@ export class RubyGemsDatasource extends Datasource {
     }
   }
 
+  @cache({
+    namespace: `datasource-${RubyGemsDatasource.id}`,
+    key: ({ registryUrl, packageName }: GetReleasesConfig) =>
+      // TODO: types (#7154)
+      /* eslint-disable @typescript-eslint/restrict-template-expressions */
+      `metadata:${registryUrl}/${packageName}`,
+  })
   async fetchGemMetadata(
     registryUrl: string,
     packageName: string
@@ -106,6 +115,13 @@ export class RubyGemsDatasource extends Datasource {
     }
   }
 
+  @cache({
+    namespace: `datasource-${RubyGemsDatasource.id}`,
+    key: ({ registryUrl, packageName }: GetReleasesConfig) =>
+      // TODO: types (#7154)
+      /* eslint-disable @typescript-eslint/restrict-template-expressions */
+      `versions:${registryUrl}/${packageName}`,
+  })
   async fetchGemVersions(
     registryUrl: string,
     packageName: string
@@ -162,6 +178,13 @@ export class RubyGemsDatasource extends Datasource {
     return result;
   }
 
+  @cache({
+    namespace: `datasource-${RubyGemsDatasource.id}`,
+    key: ({ registryUrl, packageName }: GetReleasesConfig) =>
+      // TODO: types (#7154)
+      /* eslint-disable @typescript-eslint/restrict-template-expressions */
+      `dependencies:${registryUrl}/${packageName}`,
+  })
   async getReleasesViaFallbackAPI(
     registryUrl: string,
     packageName: string