diff --git a/docs/usage/self-hosted-configuration.md b/docs/usage/self-hosted-configuration.md
index 5ba22170f99294a6cd8cedef3eadaed2744d5b27..f4e304981d1b145bee7b48263f0b87159ddc604e 100644
--- a/docs/usage/self-hosted-configuration.md
+++ b/docs/usage/self-hosted-configuration.md
@@ -83,6 +83,10 @@ Set this to true if you wish for Renovate to persist repo data between runs. The
 
 ## platform
 
+## prCommitsPerRunLimit
+
+Parameter to reduce CI load. CI jobs are usually triggered by these events: pull-request creation, pull-request update, automerge events. Set as an integer. Default is no limit.
+
 ## prFooter
 
 ## printConfig
diff --git a/lib/config/definitions.ts b/lib/config/definitions.ts
index abe48135816f6a08f4ad40e74f86cdaea66ea8f0..33b9b7966cc0dc676c862266c7aafbf39c452d9c 100644
--- a/lib/config/definitions.ts
+++ b/lib/config/definitions.ts
@@ -447,6 +447,14 @@ const options: RenovateOptions[] = [
     type: 'string',
     default: null,
   },
+  {
+    name: 'prCommitsPerRunLimit',
+    description:
+      'Set a maximum number of commits per Renovate run. Default is no limit.',
+    stage: 'global',
+    type: 'integer',
+    default: 0,
+  },
   {
     name: 'repositories',
     description: 'List of Repositories',
diff --git a/lib/platform/git/storage.ts b/lib/platform/git/storage.ts
index 2ccd3375245ceb4fbd7e37dab6e6518a10ccb9d1..bfe7bf9fa3a0c65ec366ab1606721575430fa5cf 100644
--- a/lib/platform/git/storage.ts
+++ b/lib/platform/git/storage.ts
@@ -5,6 +5,8 @@ import Git from 'simple-git/promise';
 import URL from 'url';
 import { logger } from '../../logger';
 
+const limits = require('../../workers/global/limits');
+
 declare module 'fs-extra' {
   // eslint-disable-next-line import/prefer-default-export
   export function exists(pathLike: string): Promise<boolean>;
@@ -366,6 +368,7 @@ export class Storage {
     await this._git!.checkout(this._config.baseBranch);
     await this._git!.merge(['--ff-only', branchName]);
     await this._git!.push('origin', this._config.baseBranch);
+    limits.incrementLimit('prCommitsPerRunLimit');
   }
 
   async getBranchLastCommitTime(branchName: string) {
@@ -450,6 +453,7 @@ export class Storage {
       const ref = `refs/heads/${branchName}:refs/remotes/origin/${branchName}`;
       await this._git!.fetch(['origin', ref, '--depth=2', '--force']);
       this._config.branchExists[branchName] = true;
+      limits.incrementLimit('prCommitsPerRunLimit');
     } catch (err) /* istanbul ignore next */ {
       checkForPlatformFailure(err);
       logger.debug({ err }, 'Error commiting files');
diff --git a/lib/workers/branch/index.js b/lib/workers/branch/index.js
index c7ec27623498dcf0844868464db3143719f9ba15..e6afd3d4a60eb837b69236e3caea1ac8f96aebfb 100644
--- a/lib/workers/branch/index.js
+++ b/lib/workers/branch/index.js
@@ -111,7 +111,9 @@ async function processBranch(branchConfig, prHourlyLimitReached, packageFiles) {
       !masterIssueCheck &&
       !config.vulnerabilityAlert
     ) {
-      logger.info('Reached PR creation limit - skipping branch creation');
+      logger.info(
+        'Reached PR creation limit or per run commits limit - skipping branch creation'
+      );
       return 'pr-hourly-limit-reached';
     }
     if (branchExists) {
diff --git a/lib/workers/global/index.js b/lib/workers/global/index.js
index a5564566cc7a149d4807de213e32f40c7301d4ba..a17fc66233adce7a5f32e1633197f37291383cbb 100644
--- a/lib/workers/global/index.js
+++ b/lib/workers/global/index.js
@@ -13,6 +13,7 @@ const { autodiscoverRepositories } = require('./autodiscover');
 const { initPlatform } = require('../../platform');
 const hostRules = require('../../util/host-rules');
 const { printStats } = require('../../util/got/stats');
+const limits = require('./limits');
 
 export { start, getRepositoryConfig };
 
@@ -39,9 +40,16 @@ async function start() {
     global.trustLevel = config.trustLevel || 'low';
     delete config.trustLevel;
     detectRenovateVersion();
+    limits.init(config);
     setEmojiConfig(config);
     // Iterate through repositories sequentially
     for (const repository of config.repositories) {
+      if (limits.getLimitRemaining('prCommitsPerRunLimit') <= 0) {
+        logger.info(
+          'Max commits created for this run. Skipping all remaining repositories.'
+        );
+        break;
+      }
       const repoConfig = await getRepositoryConfig(config, repository);
       if (repoConfig.hostRules) {
         hostRules.clear();
diff --git a/lib/workers/global/limits.ts b/lib/workers/global/limits.ts
new file mode 100644
index 0000000000000000000000000000000000000000..3e97cf8d719a966ce3d389222a0dafd4a91e49e7
--- /dev/null
+++ b/lib/workers/global/limits.ts
@@ -0,0 +1,41 @@
+import { logger } from '../../logger';
+
+const limitsToInit = ['prCommitsPerRunLimit'];
+const l: Record<string, number> = {};
+const v: Record<string, number> = {};
+
+export function init(config: Record<string, any>) {
+  logger.info(`Limits.init enter method`);
+  for (const limit of limitsToInit) {
+    logger.info(`Limits.init ${limit} processing`);
+    if (config[limit]) {
+      setLimit(limit, config[limit]);
+      v[limit] = 0;
+    } else {
+      logger.info(
+        `Limits.init ${limit} variable is not set. Ignoring ${limit}`
+      );
+    }
+  }
+}
+
+export function setLimit(name: string, value: number) {
+  logger.debug(`Limits.setLimit l[${name}] = ${value}`);
+  l[name] = value;
+}
+
+export function getLimitRemaining(name: string) {
+  let result;
+  if (typeof v[name] !== 'undefined') {
+    result = l[name] - v[name];
+  } else {
+    result = undefined;
+  }
+  return result;
+}
+
+export function incrementLimit(name: string, value = 1) {
+  if (typeof v[name] !== 'undefined') {
+    v[name] += value;
+  }
+}
diff --git a/lib/workers/repository/process/write.js b/lib/workers/repository/process/write.js
index 4c0daa1aa66b12238c60c8267ea962add9f77229..68857248d1f3bdb067075f2b96296f38bdfc0f02 100644
--- a/lib/workers/repository/process/write.js
+++ b/lib/workers/repository/process/write.js
@@ -1,6 +1,7 @@
 const { logger } = require('../../../logger');
 const branchWorker = require('../../branch');
 const { getPrsRemaining } = require('./limits');
+const limits = require('../../global/limits');
 
 module.exports = {
   writeUpdates,
@@ -27,7 +28,8 @@ async function writeUpdates(config, packageFiles, allBranches) {
   for (const branch of branches) {
     const res = await branchWorker.processBranch(
       branch,
-      prsRemaining <= 0,
+      prsRemaining <= 0 ||
+        limits.getLimitRemaining('prCommitsPerRunLimit') <= 0,
       packageFiles
     );
     branch.res = res;
diff --git a/renovate-schema.json b/renovate-schema.json
index 5cce87fa10f4c609038a8abe31ada3db4860ffbb..dac8e9819111e97958b61c8a6c01b3051327719b 100644
--- a/renovate-schema.json
+++ b/renovate-schema.json
@@ -235,6 +235,11 @@
       "type": "string",
       "default": null
     },
+    "prCommitsPerRunLimit": {
+      "description": "Set a maximum number of commits per Renovate run. Default is no limit.",
+      "type": "integer",
+      "default": 0
+    },
     "repositories": {
       "description": "List of Repositories",
       "type": "array"
diff --git a/test/workers/global/index.spec.js b/test/workers/global/index.spec.js
index 27f5212f04c0aee8614d32d84c6b476c4bd92e09..7e365768d5ba3bc23a6201a5ada84e56e68731eb 100644
--- a/test/workers/global/index.spec.js
+++ b/test/workers/global/index.spec.js
@@ -7,6 +7,8 @@ const platform = require('../../../lib/platform');
 
 jest.mock('../../../lib/platform');
 
+const limits = require('../../../lib/workers/global/limits');
+
 describe('lib/workers/global', () => {
   beforeEach(() => {
     jest.resetAllMocks();
@@ -50,6 +52,27 @@ describe('lib/workers/global', () => {
     expect(repositoryWorker.renovateRepository).toHaveBeenCalledTimes(2);
   });
 
+  it('processes repositories break', async () => {
+    limits.getLimitRemaining = jest.fn(() => 0);
+    // limits.getLimitRemaining.mockReturnValueOnce(0);
+    configParser.parseConfigs.mockReturnValueOnce({
+      gitAuthor: 'a@b.com',
+      enabled: true,
+      repositories: ['a', 'b'],
+      hostRules: [
+        {
+          hostType: 'docker',
+          host: 'docker.io',
+          username: 'some-user',
+          password: 'some-password',
+        },
+      ],
+    });
+    await globalWorker.start();
+    expect(configParser.parseConfigs).toHaveBeenCalledTimes(1);
+    expect(repositoryWorker.renovateRepository).toHaveBeenCalledTimes(0);
+  });
+
   describe('processes platforms', () => {
     it('github', async () => {
       configParser.parseConfigs.mockReturnValueOnce({
diff --git a/test/workers/global/limits.spec.ts b/test/workers/global/limits.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..df1b5d2ba52c0ecc8b19207a3249ec372e43bd57
--- /dev/null
+++ b/test/workers/global/limits.spec.ts
@@ -0,0 +1,25 @@
+import {
+  init,
+  getLimitRemaining,
+  incrementLimit,
+} from '../../../lib/workers/global/limits';
+
+describe('lib/workers/global/limits', () => {
+  describe('init()', () => {
+    it('check defined variables have a value set to zero', async () => {
+      const config = { prCommitsPerRunLimit: 3 };
+      init(config);
+      const result = await getLimitRemaining('prCommitsPerRunLimit');
+      expect(result).toEqual(3);
+    });
+  });
+  describe('incrementLimit()', () => {
+    it('check increment works as expected', async () => {
+      const config = { prCommitsPerRunLimit: 3 };
+      init(config);
+      incrementLimit('prCommitsPerRunLimit', 2);
+      const result = await getLimitRemaining('prCommitsPerRunLimit');
+      expect(result).toEqual(1);
+    });
+  });
+});
diff --git a/test/workers/repository/process/write.spec.js b/test/workers/repository/process/write.spec.js
index 3ea14619a5f1cd9dce89e1a7e6b4d3055cbc1f95..0a40870c9227f1ed26de091e5de5bfcc210274ab 100644
--- a/test/workers/repository/process/write.spec.js
+++ b/test/workers/repository/process/write.spec.js
@@ -5,8 +5,10 @@ const {
 const branchWorker = require('../../../../lib/workers/branch');
 /** @type any */
 const limits = require('../../../../lib/workers/repository/process/limits');
+/** @type any */
 
 branchWorker.processBranch = jest.fn();
+
 limits.getPrsRemaining = jest.fn(() => 99);
 
 let config;