diff --git a/lib/util/cache/repository/types.ts b/lib/util/cache/repository/types.ts
index 5410621bad911674ef354c3b55aa35dd50b2254c..d4753ae4929e49dca9804a7f51d018e24de95bac 100644
--- a/lib/util/cache/repository/types.ts
+++ b/lib/util/cache/repository/types.ts
@@ -38,6 +38,8 @@ export interface OnboardingBranchCache {
   onboardingBranchSha: string;
   isConflicted: boolean;
   isModified: boolean;
+  configFileName?: string;
+  configFileParsed?: string;
 }
 
 export interface PrCache {
diff --git a/lib/workers/repository/index.ts b/lib/workers/repository/index.ts
index 45103753917f34b5617adbd59ff9a14883c7e421..e19cad910c0eee7240d2c8f27568d97b9e941009 100644
--- a/lib/workers/repository/index.ts
+++ b/lib/workers/repository/index.ts
@@ -55,7 +55,7 @@ export async function renovateRepository(
     addSplit('init');
     const performExtract =
       config.repoIsOnboarded! ||
-      !config.onboardingRebaseCheckbox ||
+      !OnboardingState.onboardingCacheValid ||
       OnboardingState.prUpdateRequested;
     const { branches, branchList, packageFiles } = performExtract
       ? await instrument('extract', () => extractDependencies(config))
diff --git a/lib/workers/repository/init/merge.spec.ts b/lib/workers/repository/init/merge.spec.ts
index af798bf329a2bbff3d9e6f0d27406ca35aa70a40..28676bd9ef23b058fcac688232eb700fbd813361 100644
--- a/lib/workers/repository/init/merge.spec.ts
+++ b/lib/workers/repository/init/merge.spec.ts
@@ -10,9 +10,12 @@ import {
 import { getConfig } from '../../../config/defaults';
 import * as _migrateAndValidate from '../../../config/migrate-validate';
 import * as _migrate from '../../../config/migration';
+import * as memCache from '../../../util/cache/memory';
 import * as repoCache from '../../../util/cache/repository';
 import { initRepoCache } from '../../../util/cache/repository/init';
 import type { RepoCacheData } from '../../../util/cache/repository/types';
+import * as _onboardingCache from '../onboarding/branch/onboarding-branch-cache';
+import { OnboardingState } from '../onboarding/common';
 import {
   checkForRepoConfigError,
   detectRepoFileConfig,
@@ -21,13 +24,16 @@ import {
 
 jest.mock('../../../util/fs');
 jest.mock('../../../util/git');
+jest.mock('../onboarding/branch/onboarding-branch-cache');
 
 const migrate = mocked(_migrate);
 const migrateAndValidate = mocked(_migrateAndValidate);
+const onboardingCache = mocked(_onboardingCache);
 
 let config: RenovateConfig;
 
 beforeEach(() => {
+  memCache.init();
   jest.resetAllMocks();
   config = getConfig();
   config.errors = [];
@@ -64,6 +70,64 @@ describe('workers/repository/init/merge', () => {
       );
     });
 
+    it('returns cache config from onboarding cache - package.json', async () => {
+      const pJson = JSON.stringify({
+        schema: 'https://docs.renovate.com',
+      });
+      OnboardingState.onboardingCacheValid = true;
+      onboardingCache.getOnboardingFileNameFromCache.mockReturnValueOnce(
+        'package.json'
+      );
+      onboardingCache.getOnboardingConfigFromCache.mockReturnValueOnce(pJson);
+      expect(await detectRepoFileConfig()).toEqual({
+        configFileName: 'package.json',
+        configFileParsed: { schema: 'https://docs.renovate.com' },
+      });
+    });
+
+    it('clones, if onboarding cache is valid but parsed config is undefined', async () => {
+      OnboardingState.onboardingCacheValid = true;
+      onboardingCache.getOnboardingFileNameFromCache.mockReturnValueOnce(
+        'package.json'
+      );
+      onboardingCache.getOnboardingConfigFromCache.mockReturnValueOnce(
+        undefined as never
+      );
+      scm.getFileList.mockResolvedValueOnce(['package.json']);
+      const pJson = JSON.stringify({
+        name: 'something',
+        renovate: {
+          prHourlyLimit: 10,
+        },
+      });
+      fs.readLocalFile.mockResolvedValueOnce(pJson);
+      platform.getRawFile.mockResolvedValueOnce(pJson);
+      expect(await detectRepoFileConfig()).toEqual({
+        configFileName: 'package.json',
+        configFileParsed: { prHourlyLimit: 10 },
+      });
+    });
+
+    it('returns cache config from onboarding cache - renovate.json', async () => {
+      const configParsed = JSON.stringify({
+        schema: 'https://docs.renovate.com',
+      });
+      OnboardingState.onboardingCacheValid = true;
+      onboardingCache.getOnboardingFileNameFromCache.mockReturnValueOnce(
+        'renovate.json'
+      );
+      onboardingCache.getOnboardingConfigFromCache.mockReturnValueOnce(
+        configParsed
+      );
+      expect(await detectRepoFileConfig()).toEqual({
+        configFileName: 'renovate.json',
+        configFileParsed: {
+          schema: 'https://docs.renovate.com',
+        },
+        configFileRaw: undefined,
+      });
+    });
+
     it('uses package.json config if found', async () => {
       scm.getFileList.mockResolvedValue(['package.json']);
       const pJson = JSON.stringify({
diff --git a/lib/workers/repository/init/merge.ts b/lib/workers/repository/init/merge.ts
index 38d6a2ba0d6188a9e0443a09e08ce68ff02717cd..e26570c6382cb133225f2cb0caba172749b108b4 100644
--- a/lib/workers/repository/init/merge.ts
+++ b/lib/workers/repository/init/merge.ts
@@ -24,6 +24,12 @@ import { readLocalFile } from '../../../util/fs';
 import * as hostRules from '../../../util/host-rules';
 import * as queue from '../../../util/http/queue';
 import * as throttle from '../../../util/http/throttle';
+import {
+  getOnboardingConfigFromCache,
+  getOnboardingFileNameFromCache,
+  setOnboardingConfigDetails,
+} from '../onboarding/branch/onboarding-branch-cache';
+import { OnboardingState } from '../onboarding/common';
 import type { RepoFileConfig } from './types';
 
 async function detectConfigFile(): Promise<string | null> {
@@ -74,7 +80,13 @@ export async function detectRepoFileConfig(): Promise<RepoFileConfig> {
       delete cache.configFileName;
     }
   }
-  configFileName = (await detectConfigFile()) ?? undefined;
+
+  if (OnboardingState.onboardingCacheValid) {
+    configFileName = getOnboardingFileNameFromCache();
+  } else {
+    configFileName = (await detectConfigFile()) ?? undefined;
+  }
+
   if (!configFileName) {
     logger.debug('No renovate config file found');
     return {};
@@ -84,6 +96,16 @@ export async function detectRepoFileConfig(): Promise<RepoFileConfig> {
   // TODO #7154
   let configFileParsed: any;
   let configFileRaw: string | undefined | null;
+
+  if (OnboardingState.onboardingCacheValid) {
+    const cachedConfig = getOnboardingConfigFromCache();
+    const parsedConfig = cachedConfig ? JSON.parse(cachedConfig) : undefined;
+    if (parsedConfig) {
+      setOnboardingConfigDetails(configFileName, JSON.stringify(parsedConfig));
+      return { configFileName, configFileRaw, configFileParsed: parsedConfig };
+    }
+  }
+
   if (configFileName === 'package.json') {
     // We already know it parses
     configFileParsed = JSON.parse(
@@ -171,6 +193,8 @@ export async function detectRepoFileConfig(): Promise<RepoFileConfig> {
       'Repository config'
     );
   }
+
+  setOnboardingConfigDetails(configFileName, JSON.stringify(configFileParsed));
   return { configFileName, configFileRaw, configFileParsed };
 }
 
diff --git a/lib/workers/repository/onboarding/branch/index.spec.ts b/lib/workers/repository/onboarding/branch/index.spec.ts
index 1c30ac8a2c8a6a9386cd77a2835f1968e2a1ebf6..926ab508f7f17e048ad5560f2d1531fa27160443 100644
--- a/lib/workers/repository/onboarding/branch/index.spec.ts
+++ b/lib/workers/repository/onboarding/branch/index.spec.ts
@@ -263,6 +263,33 @@ describe('workers/repository/onboarding/branch/index', () => {
       expect(scm.commitAndPush).toHaveBeenCalledTimes(0);
     });
 
+    it('skips processing onboarding branch when main/onboarding SHAs have not changed', async () => {
+      GlobalConfig.set({ platform: 'github' });
+      const dummyCache = {
+        onboardingBranchCache: {
+          defaultBranchSha: 'default-sha',
+          onboardingBranchSha: 'onboarding-sha',
+          isConflicted: false,
+          isModified: false,
+          configFileParsed: 'raw',
+          configFileName: 'renovate.json',
+        },
+      } satisfies RepoCacheData;
+      cache.getCache.mockReturnValue(dummyCache);
+      scm.getFileList.mockResolvedValue(['package.json']);
+      platform.findPr.mockResolvedValue(null); // finds closed onboarding pr
+      platform.getBranchPr.mockResolvedValueOnce(
+        mock<Pr>({ bodyStruct: { rebaseRequested: false } })
+      ); // finds open onboarding pr
+      git.getBranchCommit
+        .mockReturnValueOnce('default-sha')
+        .mockReturnValueOnce('default-sha')
+        .mockReturnValueOnce('onboarding-sha');
+      config.onboardingRebaseCheckbox = true;
+      await checkOnboardingBranch(config);
+      expect(git.mergeBranch).not.toHaveBeenCalled();
+    });
+
     it('processes modified onboarding branch and invalidates extract cache', async () => {
       const dummyCache = {
         scan: {
diff --git a/lib/workers/repository/onboarding/branch/index.ts b/lib/workers/repository/onboarding/branch/index.ts
index a4853d1fec8ecaa64b371d252eb68d5986373899..fb881e3525edb5483a2479deb9e18e34a23e8415 100644
--- a/lib/workers/repository/onboarding/branch/index.ts
+++ b/lib/workers/repository/onboarding/branch/index.ts
@@ -51,12 +51,26 @@ export async function checkOnboardingBranch(
   // global gitAuthor will need to be used
   setGitAuthor(config.gitAuthor);
   const onboardingPr = await getOnboardingPr(config);
+  // TODO #7154
+  const branchList = [onboardingBranch!];
   if (onboardingPr) {
     if (config.onboardingRebaseCheckbox) {
       handleOnboardingManualRebase(onboardingPr);
     }
     logger.debug('Onboarding PR already exists');
 
+    if (
+      isOnboardingCacheValid(config.defaultBranch!, config.onboardingBranch!) &&
+      !(config.onboardingRebaseCheckbox && OnboardingState.prUpdateRequested)
+    ) {
+      logger.debug(
+        'Skip processing since the onboarding branch is up to date and default branch has not changed'
+      );
+      OnboardingState.onboardingCacheValid = true;
+      return { ...config, repoIsOnboarded, onboardingBranch, branchList };
+    }
+    OnboardingState.onboardingCacheValid = false;
+
     isModified = await isOnboardingBranchModified(config.onboardingBranch!);
     if (isModified) {
       if (hasOnboardingBranchChanged(config.onboardingBranch!)) {
@@ -109,8 +123,6 @@ export async function checkOnboardingBranch(
     isModified
   );
 
-  // TODO #7154
-  const branchList = [onboardingBranch!];
   return { ...config, repoIsOnboarded, onboardingBranch, branchList };
 }
 
@@ -137,3 +149,19 @@ function invalidateExtractCache(baseBranch: string): void {
     delete cache.scan[baseBranch];
   }
 }
+
+function isOnboardingCacheValid(
+  defaultBranch: string,
+  onboardingBranch: string
+): boolean {
+  const cache = getCache();
+  const onboardingBranchCache = cache?.onboardingBranchCache;
+  return !!(
+    onboardingBranchCache &&
+    onboardingBranchCache.defaultBranchSha === getBranchCommit(defaultBranch) &&
+    onboardingBranchCache.onboardingBranchSha ===
+      getBranchCommit(onboardingBranch) &&
+    onboardingBranchCache.configFileName &&
+    onboardingBranchCache.configFileParsed
+  );
+}
diff --git a/lib/workers/repository/onboarding/branch/onboarding-branch-cache.spec.ts b/lib/workers/repository/onboarding/branch/onboarding-branch-cache.spec.ts
index 40cb301774145499bebbc90201c353566d8f17e1..b1e64d0a57c203f924448a85e37dc52c16594b07 100644
--- a/lib/workers/repository/onboarding/branch/onboarding-branch-cache.spec.ts
+++ b/lib/workers/repository/onboarding/branch/onboarding-branch-cache.spec.ts
@@ -1,12 +1,18 @@
-import { git, mocked, scm } from '../../../../../test/util';
+import { git, mocked, partial, scm } from '../../../../../test/util';
 import * as _cache from '../../../../util/cache/repository';
-import type { RepoCacheData } from '../../../../util/cache/repository/types';
+import type {
+  OnboardingBranchCache,
+  RepoCacheData,
+} from '../../../../util/cache/repository/types';
 import {
   deleteOnboardingCache,
+  getOnboardingConfigFromCache,
+  getOnboardingFileNameFromCache,
   hasOnboardingBranchChanged,
   isOnboardingBranchConflicted,
   isOnboardingBranchModified,
   setOnboardingCache,
+  setOnboardingConfigDetails,
 } from './onboarding-branch-cache';
 
 jest.mock('../../../../util/cache/repository');
@@ -232,4 +238,61 @@ describe('workers/repository/onboarding/branch/onboarding-branch-cache', () => {
       ).toBeTrue();
     });
   });
+
+  describe('getOnboardingFileNameFromCache()', () => {
+    it('returns cached value', () => {
+      const dummyCache = {
+        onboardingBranchCache: partial<OnboardingBranchCache>({
+          configFileName: 'renovate.json',
+        }),
+      } satisfies RepoCacheData;
+      cache.getCache.mockReturnValueOnce(dummyCache);
+      expect(getOnboardingFileNameFromCache()).toBe('renovate.json');
+    });
+
+    it('returns undefined', () => {
+      expect(getOnboardingFileNameFromCache()).toBeUndefined();
+    });
+  });
+
+  describe('getOnboardingConfigFromCache()', () => {
+    it('returns cached value', () => {
+      const dummyCache = {
+        onboardingBranchCache: partial<OnboardingBranchCache>({
+          configFileParsed: 'parsed',
+        }),
+      } satisfies RepoCacheData;
+      cache.getCache.mockReturnValueOnce(dummyCache);
+      expect(getOnboardingConfigFromCache()).toBe('parsed');
+    });
+
+    it('returns undefined', () => {
+      expect(getOnboardingConfigFromCache()).toBeUndefined();
+    });
+  });
+
+  describe('setOnboardingConfigDetails()', () => {
+    it('returns cached value', () => {
+      const dummyCache = {
+        onboardingBranchCache: {
+          defaultBranchSha: 'default-sha',
+          onboardingBranchSha: 'onboarding-sha',
+          isConflicted: true,
+          isModified: true,
+        },
+      } satisfies RepoCacheData;
+      cache.getCache.mockReturnValueOnce(dummyCache);
+      setOnboardingConfigDetails('renovate.json', 'parsed');
+      expect(dummyCache).toEqual({
+        onboardingBranchCache: {
+          defaultBranchSha: 'default-sha',
+          onboardingBranchSha: 'onboarding-sha',
+          isConflicted: true,
+          isModified: true,
+          configFileName: 'renovate.json',
+          configFileParsed: 'parsed',
+        },
+      });
+    });
+  });
 });
diff --git a/lib/workers/repository/onboarding/branch/onboarding-branch-cache.ts b/lib/workers/repository/onboarding/branch/onboarding-branch-cache.ts
index 9f7ebd1b47cf1ba1865edd4842ce24b8ee86bc20..7917b124ab05508c21323ffa7f333481f06a5d25 100644
--- a/lib/workers/repository/onboarding/branch/onboarding-branch-cache.ts
+++ b/lib/workers/repository/onboarding/branch/onboarding-branch-cache.ts
@@ -80,6 +80,27 @@ export async function isOnboardingBranchModified(
   return isModified;
 }
 
+export function getOnboardingFileNameFromCache(): string | undefined {
+  const cache = getCache();
+  return cache.onboardingBranchCache?.configFileName;
+}
+
+export function getOnboardingConfigFromCache(): string | undefined {
+  const cache = getCache();
+  return cache.onboardingBranchCache?.configFileParsed;
+}
+
+export function setOnboardingConfigDetails(
+  configFileName: string,
+  configFileParsed: string
+): void {
+  const cache = getCache();
+  if (cache.onboardingBranchCache) {
+    cache.onboardingBranchCache.configFileName = configFileName;
+    cache.onboardingBranchCache.configFileParsed = configFileParsed;
+  }
+}
+
 export async function isOnboardingBranchConflicted(
   defaultBranch: string,
   onboardingBranch: string
diff --git a/lib/workers/repository/onboarding/common.ts b/lib/workers/repository/onboarding/common.ts
index 5738c3d09d33afa835b241c6c714f56cdb4d7d8e..d19da1ca0a492644312db6bed7f1e2a91a6fab65 100644
--- a/lib/workers/repository/onboarding/common.ts
+++ b/lib/workers/repository/onboarding/common.ts
@@ -11,6 +11,7 @@ export function defaultConfigFile(config: RenovateConfig): string {
 
 export class OnboardingState {
   private static readonly cacheKey = 'OnboardingState';
+  private static readonly skipKey = 'OnboardingStateValid';
 
   static get prUpdateRequested(): boolean {
     const updateRequested = !!memCache.get<boolean | undefined>(
@@ -27,4 +28,20 @@ export class OnboardingState {
     logger.trace({ value }, 'Set OnboardingState.prUpdateRequested');
     memCache.set(OnboardingState.cacheKey, value);
   }
+
+  static get onboardingCacheValid(): boolean {
+    const cacheValid = !!memCache.get<boolean | undefined>(
+      OnboardingState.skipKey
+    );
+    logger.trace(
+      { value: cacheValid },
+      'Get OnboardingState.onboardingCacheValid'
+    );
+    return cacheValid;
+  }
+
+  static set onboardingCacheValid(value: boolean) {
+    logger.trace({ value }, 'Set OnboardingState.onboardingCacheValid');
+    memCache.set(OnboardingState.skipKey, value);
+  }
 }
diff --git a/lib/workers/repository/onboarding/pr/index.ts b/lib/workers/repository/onboarding/pr/index.ts
index e391fc8dd008621ec701c79e9855b099e8743a5c..08b58ea760b2012a4f4de3c44e0982daf5af06b6 100644
--- a/lib/workers/repository/onboarding/pr/index.ts
+++ b/lib/workers/repository/onboarding/pr/index.ts
@@ -33,6 +33,7 @@ export async function ensureOnboardingPr(
 ): Promise<void> {
   if (
     config.repoIsOnboarded ||
+    OnboardingState.onboardingCacheValid ||
     (config.onboardingRebaseCheckbox && !OnboardingState.prUpdateRequested)
   ) {
     return;