diff --git a/Trigger/TrigMonitoring/TrigCostMonitor/TrigCostMonitor/TrigCostRun.h b/Trigger/TrigMonitoring/TrigCostMonitor/TrigCostMonitor/TrigCostRun.h
index 5fc62a5cbb5b4672fb1eb8a6dc742828f815a686..59808ed621cfadb19f8e604c8893dcb574e252ec 100644
--- a/Trigger/TrigMonitoring/TrigCostMonitor/TrigCostMonitor/TrigCostRun.h
+++ b/Trigger/TrigMonitoring/TrigCostMonitor/TrigCostMonitor/TrigCostRun.h
@@ -66,7 +66,8 @@ private:
      ~ReadHLTResult() {}
 
      bool ProcessEvent(ServiceHandle<StoreGateSvc> &storeGate, 
-		       ToolHandle<HLT::Navigation> &navigation);
+		       ToolHandle<HLT::Navigation> &navigation,
+           ToolHandle<Trig::ITrigNtTool> &confTool);
      
      void PrintInit();
      void PrintEvent();
@@ -81,7 +82,13 @@ private:
 		     ToolHandle<HLT::Navigation> &navigation);
 
      bool ReadConfig(ServiceHandle<StoreGateSvc> &storeGate);
-     bool ReadEvent (ServiceHandle<StoreGateSvc> &storeGate);
+     bool ReadConfigDB(ServiceHandle<StoreGateSvc> &storeGate, 
+                       std::set<const TrigMonEvent*> trigMonEvents,
+                       ToolHandle<Trig::ITrigNtTool> &confTool);
+
+     bool ReadEvent (ServiceHandle<StoreGateSvc> &storeGate, 
+                     const bool gotConfigSG, 
+                     ToolHandle<Trig::ITrigNtTool> &confTool);
 
      MsgStream& log() const { return *msgStream; }
 
@@ -115,6 +122,7 @@ private:
      unsigned                     countConfig;  // Count all extracted TrigMonConfig 
      unsigned                     resultPrint;  // Count all fully printed results
 
+
      std::set< std::pair<int,int> > exportedConfigs; // L1 and HLT keys of configurations which have already been exported to D3PD
    };
 
@@ -136,7 +144,9 @@ private:
 
    ToolHandleArray<Trig::ITrigNtTool>  m_tools;
    ToolHandleArray<Trig::ITrigNtTool>  m_toolsSave;
-   
+
+   ToolHandle<Trig::ITrigNtTool>       m_toolConf; //!< To read in TrigConf from the DB at T0
+
    // Variables   
    ReadHLTResult                       m_readL2;          // Helper class for reading L2 result
    ReadHLTResult                       m_readEF;          // Helper class for reading EF result
diff --git a/Trigger/TrigMonitoring/TrigCostMonitor/python/TrigCostMonitorConfig.py b/Trigger/TrigMonitoring/TrigCostMonitor/python/TrigCostMonitorConfig.py
index 5797c027336d4cd39d640986b9ceccf4b4b62acc..5f4d33dbb6a7a2eded71e5b0da01ed603b84db2d 100644
--- a/Trigger/TrigMonitoring/TrigCostMonitor/python/TrigCostMonitorConfig.py
+++ b/Trigger/TrigMonitoring/TrigCostMonitor/python/TrigCostMonitorConfig.py
@@ -56,7 +56,7 @@ def prepareCostTool(target):
     tool.monitoringTarget = target
     tool.purgeCostStream  = True  # Remove cost stream if no data to save 
     tool.writeAlways      = False # This is set to True by postSetupCostForCAF()
-    tool.writeConfig      = True  # This should default to false for online (why?) [TODO] put to true for tests
+    tool.writeConfig      = False # Now know why this should be false online, consumes too much bandwidth. Will read from COOL at T0 instead.
     tool.writeConfigDB    = False # If reading from the DB, do we want to save the data? Should not be needed as EBWeight calc is in this package.
     tool.useConfDb        = True  # Ask toolConf to fetch online config from DB. Only used currently if running costoForCAF
     tool.costForCAF       = False # This is set to True by postSetupCostForCAF()
diff --git a/Trigger/TrigMonitoring/TrigCostMonitor/src/TrigCostRun.cxx b/Trigger/TrigMonitoring/TrigCostMonitor/src/TrigCostRun.cxx
index 4bafda3d0e095237bfc5c1fd3f712445cd70ffb2..eb4c3144cf1055370a263d897949106520329a06 100644
--- a/Trigger/TrigMonitoring/TrigCostMonitor/src/TrigCostRun.cxx
+++ b/Trigger/TrigMonitoring/TrigCostMonitor/src/TrigCostRun.cxx
@@ -36,7 +36,8 @@ TrigCostRun::TrigCostRun(const std::string& name,
    m_timerSvc("TrigTimerSvc/TrigTimerSvc", name),
    m_navigation("HLT::Navigation/Navigation", this),
    m_tools(this),
-   m_toolsSave(this)
+   m_toolsSave(this),
+   m_toolConf("Trig::TrigNtConfTool/TrigNtConfTool", this)
 {
   declareProperty("navigation",    m_navigation, "Trigger navigation tool");
   declareProperty("tools",         m_tools,      "Tools array");
@@ -92,6 +93,8 @@ StatusCode TrigCostRun::initialize()
   CHECK(m_toolsSave.retrieve());
   ATH_MSG_DEBUG("Retrieved " << m_toolsSave);
 
+  CHECK(m_toolConf.retrieve());
+  ATH_MSG_DEBUG("Retrieved " << m_toolConf);
 
   //
   // Pass global configuration pointer to sub-tools
@@ -180,9 +183,9 @@ StatusCode TrigCostRun::execute()
     m_navigation->reset();
   }
 
-  m_readL2.ProcessEvent(evtStore(), m_navigation);
-  m_readEF.ProcessEvent(evtStore(), m_navigation);
-  m_readHLT.ProcessEvent(evtStore(), m_navigation);
+  m_readL2.ProcessEvent(evtStore(), m_navigation, m_toolConf);
+  m_readEF.ProcessEvent(evtStore(), m_navigation, m_toolConf);
+  m_readHLT.ProcessEvent(evtStore(), m_navigation, m_toolConf);
 
   if(m_printEvent) {
     m_readL2.PrintEvent();
@@ -342,7 +345,8 @@ TrigCostRun::ReadHLTResult::ReadHLTResult()
 
 //-----------------------------------------------------------------------------
 bool TrigCostRun::ReadHLTResult::ProcessEvent(ServiceHandle<StoreGateSvc> &storeGate, 
-					      ToolHandle<HLT::Navigation> &navigation)
+					      ToolHandle<HLT::Navigation> &navigation,
+                ToolHandle<Trig::ITrigNtTool> &confTool)
 {
   //
   // Process one event:
@@ -351,7 +355,8 @@ bool TrigCostRun::ReadHLTResult::ProcessEvent(ServiceHandle<StoreGateSvc> &store
   //  - read TrigMonEvent  collection
   //  - read TrigMonConfig collection
   //
-  
+  if(outputLevel <= MSG::DEBUG) log() << MSG::DEBUG << "In ProcessEvent" << endmsg;
+
   if (doLevel == false) return false;
   
   vecConfig.clear();
@@ -373,8 +378,12 @@ bool TrigCostRun::ReadHLTResult::ProcessEvent(ServiceHandle<StoreGateSvc> &store
   //
   // Read events and configs
   //
-  ReadConfig(storeGate);
-  ReadEvent (storeGate);
+  const bool gotConfigSG = ReadConfig(storeGate);
+  // If gotConfigSG is false, we will try again to read in from the DB configs for cost mon events stored in this dummy-export-event
+
+  if(outputLevel <= MSG::DEBUG) log() << MSG::DEBUG << "gotConfigSG = " << gotConfigSG << endmsg;
+
+  ReadEvent(storeGate, gotConfigSG, confTool);
   
   return true;
 }
@@ -522,7 +531,7 @@ bool TrigCostRun::ReadHLTResult::ReadConfig(ServiceHandle<StoreGateSvc> &storeGa
     //
     const std::vector<uint32_t> &ids = ptr->getVarId();
     if(!std::count(ids.begin(), ids.end(), appId)) {
-      // FIXME: const_cast changing SG
+      // FIXME: const_cast changing SG (TimM: 02-11-18, deprecated and not for use in Run3. Hence not fixing)
       const_cast<TrigMonConfig*>(ptr)->add<TrigConfVar>(TrigConfVar(appName, appId));
       if(outputLevel <= MSG::DEBUG) log() << MSG::DEBUG << "Attaching App Name map to Config " << appName << " = " << appId << endmsg;
     }
@@ -546,8 +555,72 @@ bool TrigCostRun::ReadHLTResult::ReadConfig(ServiceHandle<StoreGateSvc> &storeGa
 }
 
 //---------------------------------------------------------------------------------------
-bool TrigCostRun::ReadHLTResult::ReadEvent(ServiceHandle<StoreGateSvc> &storeGate)
-{
+bool TrigCostRun::ReadHLTResult::ReadConfigDB(ServiceHandle<StoreGateSvc> &storeGate, 
+  std::set<const TrigMonEvent*> trigMonEvents,
+  ToolHandle<Trig::ITrigNtTool> &confTool) {
+  //
+  // Read in trig config from data base
+  // If no configuration was exported from P1, then once we know what P1-monitoring-events
+  // are stored in this dummy-RAW-export event then we can load in these data from the DB.
+  // We put the config into storegate such that it can be then picked up by later tools &
+  // the D3PD maker
+  //
+
+  // Write me to storegate so that I can get picked up by the ntuple tools
+  TrigMonConfigCollection* trigMonConfigCollection = new TrigMonConfigCollection();
+
+  // Look at all events in this container event which come from a different LB
+  for (const TrigMonEvent* trigMonEvent : trigMonEvents) {
+    if(outputLevel <= MSG::DEBUG) log() << MSG::DEBUG << " Get config for event " << trigMonEvent->getEvent() << " lumi " << trigMonEvent->getLumi() << endmsg;
+
+    TrigMonConfig* trigMonConfig = new TrigMonConfig();
+
+    // Set the vital stats needed to identify the correct config
+    trigMonConfig->setEventID(trigMonEvent->getEvent(),
+                    trigMonEvent->getLumi(),
+                    trigMonEvent->getRun(),
+                    trigMonEvent->getSec(),
+                    trigMonEvent->getNanoSec());
+
+    confTool->SetOption(2); //2 = DBAccess
+    if (!confTool->Fill(trigMonConfig)) {    // false indicates nothing changed
+      if(outputLevel <= MSG::DEBUG) log() << MSG::DEBUG << "   Keys did not change in this LB, no need to update. (SMK:" << trigMonConfig->getMasterKey() << " L1:" << trigMonConfig->getLV1PrescaleKey() << " HLT:" << trigMonConfig->getHLTPrescaleKey() << ")" << endmsg;
+      delete trigMonConfig;
+      continue;
+    }
+
+    if(outputLevel <= MSG::DEBUG) log() << MSG::DEBUG << "   Loaded from DB-fetcher SMK:" << trigMonConfig->getMasterKey() << " L1:" << trigMonConfig->getLV1PrescaleKey() << " HLT:" << trigMonConfig->getHLTPrescaleKey() << endmsg;
+
+    // Have we already saved this config? Note this is set in the next fn so we could end up with dupes here (not harmful)
+    std::pair<int,int> prescaleKeys( trigMonConfig->getLV1PrescaleKey(), trigMonConfig->getHLTPrescaleKey() );
+    if ( exportedConfigs.find(prescaleKeys) != exportedConfigs.end() ) {
+      if(outputLevel <= MSG::DEBUG) log() << MSG::DEBUG << "   Already exported for L1 " << trigMonConfig->getLV1PrescaleKey() << " HLT " << trigMonConfig->getHLTPrescaleKey() << endmsg;
+      delete trigMonConfig;
+      continue;
+    }
+
+    // Add to the export list
+    if(outputLevel <= MSG::DEBUG) log() << MSG::DEBUG << "   Adding to SG" << endmsg;
+    trigMonConfigCollection->push_back(trigMonConfig);
+  }
+
+
+  if(storeGate->record(trigMonConfigCollection, keyConfig).isFailure()) {
+    log() << MSG::ERROR << "Failed to write TrigMonEventCollection: " << keyConfig << endmsg;
+    for (TrigMonConfig* trigMonConfig : *trigMonConfigCollection) delete trigMonConfig;
+    delete trigMonConfigCollection;
+    return false;
+  }
+
+  // No that we know it should (must!) be there - try again to read it!
+  return ReadConfig(storeGate);
+}
+
+//---------------------------------------------------------------------------------------
+bool TrigCostRun::ReadHLTResult::ReadEvent(ServiceHandle<StoreGateSvc> &storeGate, 
+  const bool gotConfigSG,
+  ToolHandle<Trig::ITrigNtTool> &confTool) {
+  if(outputLevel <= MSG::DEBUG) log() << MSG::DEBUG  << "In ReadEvent" << endmsg;
 
   if (doLevel == false) return false;
   
@@ -575,16 +648,40 @@ bool TrigCostRun::ReadHLTResult::ReadEvent(ServiceHandle<StoreGateSvc> &storeGat
   std::vector<std::string> &vars = globalConfig->getVarName();
   std::vector<uint32_t>    &vals = globalConfig->getVarId();
 
+  // If we did not get config data from the bytestream - fetch it for all the events we have in this carrier "event"
+  if (!gotConfigSG) {
+    std::set<uint32_t> lumiBlocks; // Only need one event per LB as a LB must have the same HLT config
+    std::set<const TrigMonEvent*> eventsToGetConfig; // Set of events we need to see if we have the config loaded for
+    for(TrigMonEventCollection::const_iterator it = eventCol->begin(); it != eventCol->end(); ++it) {
+      const TrigMonEvent *ptr = *it;
+      if(!ptr) continue;
+      if(outputLevel <= MSG::DEBUG) log() << MSG::DEBUG << "Check Conf for event " << ptr->getEvent() << " lumi " << ptr->getLumi() << "? -> ";
+
+      if (lumiBlocks.find(ptr->getLumi()) != lumiBlocks.end()) {
+        if(outputLevel <= MSG::DEBUG) log() << MSG::DEBUG << "No already have an event from lumi " << ptr->getLumi() << endmsg;
+        continue;
+      }
+
+      eventsToGetConfig.insert(ptr);
+      lumiBlocks.insert(ptr->getLumi());
+      if(outputLevel <= MSG::DEBUG) log() << MSG::DEBUG << "Yes checking this event" << endmsg;
+    }
+    // Read in all the configs for these events
+    ReadConfigDB(storeGate, eventsToGetConfig, confTool);
+  }
+
+  // Second loop - read events
   for(TrigMonEventCollection::const_iterator it = eventCol->begin(); it != eventCol->end(); ++it) {
     const TrigMonEvent *ptr = *it;
     if(!ptr) continue;
+    if(outputLevel <= MSG::DEBUG) log() << MSG::DEBUG << "Extracting Cost Data for event " << ptr->getEvent() << endmsg;
 
     // Add my HLT node
-    // FIXME: const_cast changing SG
+    // FIXME: const_cast changing SG (TimM: 02-11-18, deprecated and not for use in Run3. Hence not fixing)
     const_cast<TrigMonEvent*>(ptr)->addWord(appId); //Backward compatability
 
     if(fill_size) {
-      // FIXME: const_cast changing SG
+      // FIXME: const_cast changing SG (TimM: 02-11-18, deprecated and not for use in Run3. Hence not fixing)
       const_cast<TrigMonEvent*>(ptr)->addVar(Trig::kEventBufferSize, float(eventCol->size()));
       fill_size = false;
     }
@@ -614,7 +711,7 @@ bool TrigCostRun::ReadHLTResult::ReadEvent(ServiceHandle<StoreGateSvc> &storeGat
         log() << MSG::INFO << "Reading lumi length" << endmsg;
         m_readLumiBlock.updateLumiBlocks( ptr->getRun() );
       }
-      // FIXME: const-cast changing SG
+      // FIXME: const-cast changing SG (TimM: 02-11-18, deprecated and not for use in Run3. Hence not fixing)
       const_cast<TrigMonEvent*>(ptr)->addVar(Trig::kEventLumiBlockLength, m_readLumiBlock.getLumiBlockLength(ptr->getLumi())); // 43 is lumi block length
       if(outputLevel <= MSG::DEBUG) log() << MSG::DEBUG << "Decorating Event:" << ptr->getEvent() << "  LB:"<< ptr->getLumi()<<" with LB Length " << m_readLumiBlock.getLumiBlockLength( ptr->getLumi()) << endmsg;
       std::string msg = m_readLumiBlock.infos();
diff --git a/Trigger/TrigMonitoring/TrigCostMonitor/src/TrigCostTool.cxx b/Trigger/TrigMonitoring/TrigCostMonitor/src/TrigCostTool.cxx
index bbe0e5f43a002ec2f3f010ff4b9c76935b097d7f..3c0df3534548a7c9ca3bf23fdef1070fe064e594 100644
--- a/Trigger/TrigMonitoring/TrigCostMonitor/src/TrigCostTool.cxx
+++ b/Trigger/TrigMonitoring/TrigCostMonitor/src/TrigCostTool.cxx
@@ -654,8 +654,8 @@ void TrigCostTool::ProcessConfig(xAOD::EventInfo* info)
 
       bool writeConfig = true;
       if      (m_writeAlways == true) writeConfig = true; // First check WriteAlways flag
-      else if (m_writeConfig == false) writeConfig = false; // Next comes WriteConfig flag. This is normally true.
       else if (m_costForCAF == true) writeConfig = true; // If offline, then we don't have any other preconditions
+      else if (m_writeConfig == false) writeConfig = false; // Next comes WriteConfig flag. In 2017 this will be false online
       else if (m_obeyCostChainPS == true && m_costChainPS > 0) writeConfig = true; // Online, we normally only write out if we are in stable beams
       else if (m_obeyCostChainPS == true && m_costChainPS <= 0) writeConfig = false;
       
diff --git a/Trigger/TrigMonitoring/TrigCostMonitor/src/TrigNtConfTool.cxx b/Trigger/TrigMonitoring/TrigCostMonitor/src/TrigNtConfTool.cxx
index b650c10f1e70b5bfc47cd6f9169d4131dc7568e5..ed424e1312687292d4362b9e25774f75f0fc25ea 100644
--- a/Trigger/TrigMonitoring/TrigCostMonitor/src/TrigNtConfTool.cxx
+++ b/Trigger/TrigMonitoring/TrigCostMonitor/src/TrigNtConfTool.cxx
@@ -444,12 +444,11 @@ bool Trig::TrigNtConfTool::ReadFromDB(TrigMonConfig &confg, unsigned run, unsign
 {
   
   // Do we need to update? (note that if we do, this also sets m_currentKey)
-  if (GetKeysChangedFromDB(run, lumi) == false) {
-    return false; // Nothing to do
-  }
-
+  const bool getChanged = GetKeysChangedFromDB(run, lumi);
   confg.setTriggerKeys(m_currentKey.getSMK(), m_currentKey.getLV1_PS(), m_currentKey.getHLT_PS());
 
+  if (getChanged == false) return false; // Nothing to do
+
   std::stringstream ss1, ss2, ss3;
   ss1 << m_currentKey.getSMK();
   ss1 >> m_triggerMenuSetup;
diff --git a/Trigger/TrigMonitoring/TrigCostMonitor/src/TrigNtEBWeightTool.cxx b/Trigger/TrigMonitoring/TrigCostMonitor/src/TrigNtEBWeightTool.cxx
index 260f11dc7136bbef469962a336e1622e14122953..2936f67b88104cd49c3b0d4d3fe582ba8d43791c 100644
--- a/Trigger/TrigMonitoring/TrigCostMonitor/src/TrigNtEBWeightTool.cxx
+++ b/Trigger/TrigMonitoring/TrigCostMonitor/src/TrigNtEBWeightTool.cxx
@@ -101,7 +101,7 @@ bool Trig::TrigNtEBWeightTool::Fill(TrigMonConfig *config)
     m_chainEnabled[EBEnum] = true; // Start off assuming enabled
 
     // Get the L1 chain
-    // This depends on the _original_ menu. So for all data12, it will be L2_ even if reprocessed.
+    // This depends on the origional_ menu. So for all data12, it will be L2_ even if reprocessed.
     // Loop over all chains
 
     std::string EBChain = EBTriggerNameHLT[EB];
@@ -295,7 +295,7 @@ bool Trig::TrigNtEBWeightTool::Fill(TrigMonEvent &event)
         //if (L1Name.find("RD0") != std::string::npos || L1Name.find("RD1") != std::string::npos)  continue;
 
         // Get if this L1 item *could* have passed the event. unless it's a random streamer then it must be after veto
-        //if ( _costData_L1.getIsL1PassedBeforePrescale( _L1Name ) == kFALSE ) continue;
+        //if ( costData_L1.getIsL1PassedBeforePrescale( L1Name ) == kFALSE ) continue;
         Int_t passedL1Raw = 0;
         for (unsigned i = 0; i < eventL1Items.size(); ++i) {
           if (eventL1Items.at(i).getCtpId() != L1CPTID) continue;