diff --git a/src/applications/config/option/PhabricatorCoreConfigOptions.php b/src/applications/config/option/PhabricatorCoreConfigOptions.php
--- a/src/applications/config/option/PhabricatorCoreConfigOptions.php
+++ b/src/applications/config/option/PhabricatorCoreConfigOptions.php
@@ -214,12 +214,35 @@
         ->setDescription(pht('Cache namespace.')),
       $this->newOption('phabricator.allow-email-users', 'bool', false)
         ->setBoolOptions(
-            array(
-              pht('Allow'),
-              pht('Disallow'),
-              ))->setDescription(
-                 pht(
-                   'Allow non-members to interact with tasks over email.')),
+          array(
+            pht('Allow'),
+            pht('Disallow'),
+          ))
+        ->setDescription(
+           pht('Allow non-members to interact with tasks over email.')),
+      $this->newOption('phabricator.silent', 'bool', false)
+        ->setLocked(true)
+        ->setBoolOptions(
+          array(
+            pht('Run Silently'),
+            pht('Run Normally'),
+          ))
+        ->setSummary(pht('Stop Phabricator from sending any email, etc.'))
+        ->setDescription(
+          pht(
+            'This option allows you to stop Phabricator from sending '.
+            'any data to external services. Among other things, it will '.
+            'disable email, SMS, repository mirroring, and HTTP hooks.'.
+            "\n\n".
+            'This option is intended to allow a Phabricator instance to '.
+            'be exported, copied, imported, and run in a test environment '.
+            'without impacting users. For example, if you are migrating '.
+            'to new hardware, you could perform a test migration first, '.
+            'make sure things work, and then do a production cutover '.
+            'later with higher confidence and less disruption. Without '.
+            'this flag, users would receive duplicate email during the '.
+            'time the test instance and old production instance were '.
+            'both in operation.')),
       );
 
   }
diff --git a/src/applications/diffusion/controller/DiffusionRepositoryEditMainController.php b/src/applications/diffusion/controller/DiffusionRepositoryEditMainController.php
--- a/src/applications/diffusion/controller/DiffusionRepositoryEditMainController.php
+++ b/src/applications/diffusion/controller/DiffusionRepositoryEditMainController.php
@@ -126,7 +126,15 @@
 
       $boxes[] = id(new PhabricatorAnchorView())->setAnchorName('mirrors');
 
+      $mirror_info = array();
+      if (PhabricatorEnv::getEnvConfig('phabricator.silent')) {
+        $mirror_info[] = pht(
+          'Phabricator is running in silent mode, so changes will not '.
+          'be pushed to mirrors.');
+      }
+
       $boxes[] = id(new PHUIObjectBoxView())
+        ->setFormErrors($mirror_info)
         ->setHeaderText(pht('Mirrors'))
         ->addPropertyList($mirror_properties);
 
diff --git a/src/applications/doorkeeper/worker/DoorkeeperFeedWorker.php b/src/applications/doorkeeper/worker/DoorkeeperFeedWorker.php
--- a/src/applications/doorkeeper/worker/DoorkeeperFeedWorker.php
+++ b/src/applications/doorkeeper/worker/DoorkeeperFeedWorker.php
@@ -157,6 +157,11 @@
    * @{method:publishFeedStory}.
    */
   final protected function doWork() {
+    if (PhabricatorEnv::getEnvConfig('phabricator.silent')) {
+      $this->log(pht('Phabricator is running in silent mode.'));
+      return;
+    }
+
     if (!$this->isEnabled()) {
       $this->log("Doorkeeper worker '%s' is not enabled.\n", get_class($this));
       return;
diff --git a/src/applications/feed/worker/FeedPublisherHTTPWorker.php b/src/applications/feed/worker/FeedPublisherHTTPWorker.php
--- a/src/applications/feed/worker/FeedPublisherHTTPWorker.php
+++ b/src/applications/feed/worker/FeedPublisherHTTPWorker.php
@@ -3,6 +3,11 @@
 final class FeedPublisherHTTPWorker extends FeedPushWorker {
 
   protected function doWork() {
+    if (PhabricatorEnv::getEnvConfig('phabricator.silent')) {
+      // Don't invoke hooks in silent mode.
+      return;
+    }
+
     $story = $this->loadFeedStory();
     $data = $story->getStoryData();
 
diff --git a/src/applications/metamta/storage/PhabricatorMetaMTAMail.php b/src/applications/metamta/storage/PhabricatorMetaMTAMail.php
--- a/src/applications/metamta/storage/PhabricatorMetaMTAMail.php
+++ b/src/applications/metamta/storage/PhabricatorMetaMTAMail.php
@@ -633,6 +633,15 @@
         }
       }
 
+      if (PhabricatorEnv::getEnvConfig('phabricator.silent')) {
+        $this->setStatus(self::STATUS_VOID);
+        $this->setMessage(
+          pht(
+            'Phabricator is running in silent mode. See `phabricator.silent` '.
+            'in the configuration to change this setting.'));
+        return $this->save();
+      }
+
       $mailer->addHeader('X-Phabricator-Sent-This-Message', 'Yes');
       $mailer->addHeader('X-Mail-Transport-Agent', 'MetaMTA');
 
diff --git a/src/applications/repository/engine/PhabricatorRepositoryMirrorEngine.php b/src/applications/repository/engine/PhabricatorRepositoryMirrorEngine.php
--- a/src/applications/repository/engine/PhabricatorRepositoryMirrorEngine.php
+++ b/src/applications/repository/engine/PhabricatorRepositoryMirrorEngine.php
@@ -13,6 +13,12 @@
       return;
     }
 
+    if (PhabricatorEnv::getEnvConfig('phabricator.silent')) {
+      $this->log(
+        pht('Phabricator is running in silent mode; declining to mirror.'));
+      return;
+    }
+
     $mirrors = id(new PhabricatorRepositoryMirrorQuery())
       ->setViewer($this->getViewer())
       ->withRepositoryPHIDs(array($repository->getPHID()))
diff --git a/src/infrastructure/sms/worker/PhabricatorSMSSendWorker.php b/src/infrastructure/sms/worker/PhabricatorSMSSendWorker.php
--- a/src/infrastructure/sms/worker/PhabricatorSMSSendWorker.php
+++ b/src/infrastructure/sms/worker/PhabricatorSMSSendWorker.php
@@ -55,6 +55,15 @@
     // give the provider name the same treatment as phone number
     $sms->setProviderShortName($adapter->getProviderShortName());
 
+    if (PhabricatorEnv::getEnvConfig('phabricator.silent')) {
+      $sms->setSendStatus(PhabricatorSMS::STATUS_FAILED_PERMANENTLY);
+      $sms->save();
+      throw new PhabricatorWorkerPermanentFailureException(
+        pht(
+          'Phabricator is running in silent mode. See `phabricator.silent` '.
+          'in the configuration to change this setting.'));
+    }
+
     try {
       $result = $adapter->send();
       list($sms_id, $sent_status) = $adapter->getSMSDataFromResult($result);
diff --git a/src/infrastructure/testing/PhabricatorTestCase.php b/src/infrastructure/testing/PhabricatorTestCase.php
--- a/src/infrastructure/testing/PhabricatorTestCase.php
+++ b/src/infrastructure/testing/PhabricatorTestCase.php
@@ -119,6 +119,9 @@
     $this->env->overrideEnvConfig(
       'phabricator.base-uri',
       'http://phabricator.example.com');
+
+    // Tests do their own stubbing/voiding for events.
+    $this->env->overrideEnvConfig('phabricator.silent', false);
   }
 
   protected function didRunTests() {