diff --git a/docs/local-development.md b/docs/local-development.md
index 2a97a8a49ad0551134e09047c5327366fae64020..1727e0124f3450cb3ed769fca7e2d168cae0aff2 100644
--- a/docs/local-development.md
+++ b/docs/local-development.md
@@ -117,7 +117,7 @@ We wish to keep backwards-compatibility as often as possible, as well as make
 the code configurable, so most new functionality should be controllable via
 configuration options.
 
-If you wish to add one, add it to `lib/config/definitions.js` and then add documentation to `website/docs/_posts/2017-10-05-configuration-options.md`.
+If you wish to add one, add it to `lib/config/definitions.js` and then add documentation to `website/docs/configuration-options.md`.
 
 ## Debugging
 
diff --git a/lib/config/definitions.js b/lib/config/definitions.js
index 909f67ccf56cdbce1728ea08f33efb2d85f74105..92e9422c9c6360a32bdc3395ac663516a6c1141c 100644
--- a/lib/config/definitions.js
+++ b/lib/config/definitions.js
@@ -1847,6 +1847,12 @@ const options = [
     mergeable: true,
     cli: false,
   },
+  {
+    name: 'pruneStaleBranches',
+    description: `Enable or disable pruning of stale branches`,
+    type: 'boolean',
+    default: true,
+  },
 ];
 
 function getOptions() {
diff --git a/lib/workers/repository/finalise/prune.js b/lib/workers/repository/finalise/prune.js
index bb858fb72e4836996cbd65309cad43672ceb4b48..da3bd78ff310ea8aa8eeadd83db91b9b3f7d66ae 100644
--- a/lib/workers/repository/finalise/prune.js
+++ b/lib/workers/repository/finalise/prune.js
@@ -4,24 +4,35 @@ module.exports = {
   pruneStaleBranches,
 };
 
-async function cleanUpBranches({ dryRun }, remainingBranches) {
+async function cleanUpBranches(
+  { dryRun, pruneStaleBranches: enabled },
+  remainingBranches
+) {
   for (const branchName of remainingBranches) {
     try {
       const pr = await platform.findPr(branchName, null, 'open');
       if (pr) {
         if (!pr.title.endsWith('- autoclosed')) {
-          if (dryRun)
+          if (dryRun) {
             logger.info(
               `DRY-RUN: Would update pr ${pr.number} to ${pr.title} - autoclosed`
             );
-          else await platform.updatePr(pr.number, `${pr.title} - autoclosed`);
+          } else if (enabled === false) {
+            logger.info(
+              `PRUNING-DISABLED: Would update pr ${pr.number} to ${pr.title} - autoclosed`
+            );
+          } else await platform.updatePr(pr.number, `${pr.title} - autoclosed`);
         }
       }
       const closePr = true;
       logger.info({ branch: branchName }, `Deleting orphan branch`);
-      if (dryRun)
+      if (dryRun) {
         logger.info(`DRY-RUN: Would deleting orphan branch ${branchName}`);
-      else await platform.deleteBranch(branchName, closePr);
+      } else if (enabled === false) {
+        logger.info(
+          `PRUNING-DISABLED: Would deleting orphan branch ${branchName}`
+        );
+      } else await platform.deleteBranch(branchName, closePr);
       if (pr) {
         logger.info({ prNo: pr.number, prTitle: pr.title }, 'PR autoclosed');
       }
diff --git a/renovate-schema.json b/renovate-schema.json
index 52868c23f5e4a226f32fd71dc834d3380cc423d2..cd33efaf8114c4a3e7ea77fa81b61ef3f081b801 100644
--- a/renovate-schema.json
+++ b/renovate-schema.json
@@ -1265,6 +1265,11 @@
         "rangeStrategy": "bump"
       },
       "$ref": "#"
+    },
+    "pruneStaleBranches": {
+      "description": "Enable or disable pruning of stale branches",
+      "type": "boolean",
+      "default": true
     }
   }
 }
diff --git a/test/workers/repository/finalise/prune.spec.js b/test/workers/repository/finalise/prune.spec.js
index f0a9d3153226ce004f656ea6573f3cf187c28caa..2acbfa565d56281363694c25628202a6e1c15329 100644
--- a/test/workers/repository/finalise/prune.spec.js
+++ b/test/workers/repository/finalise/prune.spec.js
@@ -55,5 +55,18 @@ describe('workers/repository/finalise/prune', () => {
       expect(platform.deleteBranch).toHaveBeenCalledTimes(0);
       expect(platform.updatePr).toHaveBeenCalledTimes(0);
     });
+    it('does nothing on prune stale branches disabled', async () => {
+      config.branchList = ['renovate/a', 'renovate/b'];
+      config.dryRun = false;
+      config.pruneStaleBranches = false;
+      platform.getAllRenovateBranches.mockReturnValueOnce(
+        config.branchList.concat(['renovate/c'])
+      );
+      platform.findPr.mockReturnValueOnce({ title: 'foo' });
+      await cleanup.pruneStaleBranches(config, config.branchList);
+      expect(platform.getAllRenovateBranches).toHaveBeenCalledTimes(1);
+      expect(platform.deleteBranch).toHaveBeenCalledTimes(0);
+      expect(platform.updatePr).toHaveBeenCalledTimes(0);
+    });
   });
 });
diff --git a/website/docs/configuration-options.md b/website/docs/configuration-options.md
index b5cacfa049ec8185b647e3d8ec87c694347920de..11184606502c5dbb0becfd30c5e590413cb411aa 100644
--- a/website/docs/configuration-options.md
+++ b/website/docs/configuration-options.md
@@ -911,6 +911,11 @@ If you set `prCreation=not-pending`, then Renovate will wait until tests are non
 
 The PR title is important for some of Renovate's matching algorithms (e.g. determining whether to recreate a PR or not) so ideally don't modify it much.
 
+## pruneStaleBranches
+
+Set to `false` to disable deleting orphan branches and autoclosing PRs.
+Defaults to `true`.
+
 ## pub
 
 ## python