diff --git a/src/bitcoind.cpp b/src/bitcoind.cpp
--- a/src/bitcoind.cpp
+++ b/src/bitcoind.cpp
@@ -17,7 +17,6 @@
 #include "init.h"
 #include "noui.h"
 #include "rpc/server.h"
-#include "scheduler.h"
 #include "util.h"
 #include "utilstrencodings.h"
 #if ENABLE_WALLET
@@ -50,14 +49,11 @@
  * <code>Files</code> at the top of the page to start navigating the code.
  */
 
-void WaitForShutdown(boost::thread_group *threadGroup) {
+void WaitForShutdown() {
     while (!ShutdownRequested()) {
         MilliSleep(200);
     }
-    if (threadGroup) {
-        Interrupt(*threadGroup);
-        threadGroup->join_all();
-    }
+    Interrupt();
 }
 
 //////////////////////////////////////////////////////////////////////////////
@@ -65,9 +61,6 @@
 // Start
 //
 bool AppInit(int argc, char *argv[]) {
-    boost::thread_group threadGroup;
-    CScheduler scheduler;
-
     // FIXME: Ideally, we'd like to build the config here, but that's currently
     // not possible as the whole application has too many global state. However,
     // this is a first step.
@@ -189,8 +182,7 @@
             // If locking the data directory failed, exit immediately
             exit(EXIT_FAILURE);
         }
-        fRet = AppInitMain(config, httpRPCRequestProcessor, threadGroup,
-                           scheduler);
+        fRet = AppInitMain(config, httpRPCRequestProcessor);
     } catch (const std::exception &e) {
         PrintExceptionContinue(&e, "AppInit()");
     } catch (...) {
@@ -198,13 +190,9 @@
     }
 
     if (!fRet) {
-        Interrupt(threadGroup);
-        // threadGroup.join_all(); was left out intentionally here, because we
-        // didn't re-test all of the startup-failure cases to make sure they
-        // don't result in a hang due to some
-        // thread-blocking-waiting-for-another-thread-during-startup case.
+        Interrupt();
     } else {
-        WaitForShutdown(&threadGroup);
+        WaitForShutdown();
     }
     Shutdown();
 
diff --git a/src/init.h b/src/init.h
--- a/src/init.h
+++ b/src/init.h
@@ -26,7 +26,7 @@
 void StartShutdown();
 bool ShutdownRequested();
 /** Interrupt threads */
-void Interrupt(boost::thread_group &threadGroup);
+void Interrupt();
 void Shutdown();
 //! Initialize the logging infrastructure
 void InitLogging();
@@ -71,8 +71,7 @@
  * AppInitLockDataDirectory should have been called.
  */
 bool AppInitMain(Config &config,
-                 HTTPRPCRequestProcessor &httpRPCRequestProcessor,
-                 boost::thread_group &threadGroup, CScheduler &scheduler);
+                 HTTPRPCRequestProcessor &httpRPCRequestProcessor);
 
 /** The help message mode determines what help message to show */
 enum HelpMessageMode { HMM_BITCOIND, HMM_BITCOIN_QT };
diff --git a/src/init.cpp b/src/init.cpp
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -159,7 +159,10 @@
 static std::unique_ptr<CCoinsViewErrorCatcher> pcoinscatcher;
 static std::unique_ptr<ECCVerifyHandle> globalVerifyHandle;
 
-void Interrupt(boost::thread_group &threadGroup) {
+static boost::thread_group threadGroup;
+static CScheduler scheduler;
+
+void Interrupt() {
     InterruptHTTPServer();
     InterruptHTTPRPC();
     InterruptRPC();
@@ -169,7 +172,6 @@
     if (g_connman) {
         g_connman->Interrupt();
     }
-    threadGroup.interrupt_all();
 }
 
 void Shutdown() {
@@ -202,6 +204,12 @@
     g_connman.reset();
 
     StopTorControl();
+
+    // After everything has been shut down, but before things get flushed, stop
+    // the CScheduler/checkqueue threadGroup
+    threadGroup.interrupt_all();
+    threadGroup.join_all();
+
     if (fDumpMempoolLater &&
         gArgs.GetArg("-persistmempool", DEFAULT_PERSIST_MEMPOOL)) {
         DumpMempool();
@@ -1107,8 +1115,7 @@
 }
 
 static bool AppInitServers(Config &config,
-                           HTTPRPCRequestProcessor &httpRPCRequestProcessor,
-                           boost::thread_group &threadGroup) {
+                           HTTPRPCRequestProcessor &httpRPCRequestProcessor) {
     RPCServerSignals::OnStarted(&OnRPCStarted);
     RPCServerSignals::OnStopped(&OnRPCStopped);
     if (!InitHTTPServer(config)) {
@@ -1733,8 +1740,7 @@
 }
 
 bool AppInitMain(Config &config,
-                 HTTPRPCRequestProcessor &httpRPCRequestProcessor,
-                 boost::thread_group &threadGroup, CScheduler &scheduler) {
+                 HTTPRPCRequestProcessor &httpRPCRequestProcessor) {
     // Step 4a: application initialization
     const CChainParams &chainparams = config.GetChainParams();
 
@@ -1796,7 +1802,7 @@
      */
     if (gArgs.GetBoolArg("-server", false)) {
         uiInterface.InitMessage.connect(SetRPCWarmupStatus);
-        if (!AppInitServers(config, httpRPCRequestProcessor, threadGroup)) {
+        if (!AppInitServers(config, httpRPCRequestProcessor)) {
             return InitError(
                 _("Unable to start HTTP server. See debug log for details."));
         }
diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp
--- a/src/qt/bitcoin.cpp
+++ b/src/qt/bitcoin.cpp
@@ -29,7 +29,6 @@
 
 #include "init.h"
 #include "rpc/server.h"
-#include "scheduler.h"
 #include "ui_interface.h"
 #include "uint256.h"
 #include "util.h"
@@ -195,9 +194,6 @@
     void runawayException(const QString &message);
 
 private:
-    boost::thread_group threadGroup;
-    CScheduler scheduler;
-
     /// Pass fatal exception message to UI thread
     void handleRunawayException(const std::exception *e);
 };
@@ -297,8 +293,7 @@
     Config &config(*cfg);
     try {
         qDebug() << __func__ << ": Running initialization in thread";
-        bool rv = AppInitMain(config, *httpRPCRequestProcessor, threadGroup,
-                              scheduler);
+        bool rv = AppInitMain(config, *httpRPCRequestProcessor);
         Q_EMIT initializeResult(rv);
     } catch (const std::exception &e) {
         handleRunawayException(&e);
@@ -310,8 +305,7 @@
 void BitcoinABC::shutdown() {
     try {
         qDebug() << __func__ << ": Running Shutdown in thread";
-        Interrupt(threadGroup);
-        threadGroup.join_all();
+        Interrupt();
         Shutdown();
         qDebug() << __func__ << ": Shutdown finished";
         Q_EMIT shutdownResult();