diff --git a/HLT/Trigger/TrigControl/TrigServices/CMakeLists.txt b/HLT/Trigger/TrigControl/TrigServices/CMakeLists.txt
index 3bcc59c935c0036a947dffe9a1273fab2c72ff82..2228ea3f2506e720d7ca6409e2160138433e36a1 100644
--- a/HLT/Trigger/TrigControl/TrigServices/CMakeLists.txt
+++ b/HLT/Trigger/TrigControl/TrigServices/CMakeLists.txt
@@ -22,7 +22,7 @@ atlas_add_component( TrigServices
                      ${TDAQ-COMMON_LIBRARIES} ${TDAQ_LIBRARIES} ${CORAL_LIBRARIES}
                      AthenaBaseComps AthenaInterprocess AthenaKernel AthenaMonitoringKernelLib AthenaPoolUtilities
                      ByteStreamCnvSvcBaseLib ByteStreamData EventInfoUtils GaudiKernel RDBAccessSvcLib StoreGateLib TrigKernel
-                     TrigOutputHandlingLib TrigSteeringEvent TrigSteerMonitorLib xAODEventInfo xAODTrigger )
+                     TrigDataAccessMonitoringLib TrigOutputHandlingLib TrigSteeringEvent TrigSteerMonitorLib xAODEventInfo xAODTrigger )
 
 # Install files from the package:
 atlas_install_python_modules( python/*.py
diff --git a/HLT/Trigger/TrigControl/TrigServices/src/HltROBDataProviderSvc.cxx b/HLT/Trigger/TrigControl/TrigServices/src/HltROBDataProviderSvc.cxx
index a9d7030af49dff0e35d0904fe73616a4f38398d5..8e05cc2711e7ff3a6e7720eb6719828b787fb06e 100644
--- a/HLT/Trigger/TrigControl/TrigServices/src/HltROBDataProviderSvc.cxx
+++ b/HLT/Trigger/TrigControl/TrigServices/src/HltROBDataProviderSvc.cxx
@@ -143,6 +143,8 @@ StatusCode HltROBDataProviderSvc::initialize()
   // Retrieve the monitoring tool
   if (!m_monTool.empty()) ATH_CHECK(m_monTool.retrieve());
 
+  if (m_doCostMonitoring) ATH_CHECK(m_trigCostSvcHandle.retrieve());
+
   return(StatusCode::SUCCESS);
 }
 
@@ -327,6 +329,19 @@ void HltROBDataProviderSvc::getROBData(const EventContext& context,
   // check input ROB list against cache
   eventCache_checkRobListToCache(cache, robIds, robFragments, robIds_missing) ;
 
+  // check if event should be monitored
+  if (m_doCostMonitoring && m_trigCostSvcHandle->isMonitoredEvent(context, /*includeMultiSlot =*/ false)) {
+
+    for (const uint32_t id : robIds) {
+      auto ROBData = robmonitor::ROBDataStruct(id);
+
+      if (m_trigCostSvcHandle->monitorROS(context, std::move(ROBData)).isFailure()) {
+        ATH_MSG_WARNING("TrigCost ROS monitoring failed!");
+      }
+    }
+  }
+
+
   // no missing ROB fragments, return the found ROB fragments 
   if (robIds_missing.size() == 0) {
     ATH_MSG_DEBUG( __FUNCTION__ << ": All requested ROB Ids were found in the cache. "); 
diff --git a/HLT/Trigger/TrigControl/TrigServices/src/HltROBDataProviderSvc.h b/HLT/Trigger/TrigControl/TrigServices/src/HltROBDataProviderSvc.h
index 1a526c415c45479e7984a36e4e39face361bf778..ea7aac93832b2edc633ba6d379491a91d28a49f0 100644
--- a/HLT/Trigger/TrigControl/TrigServices/src/HltROBDataProviderSvc.h
+++ b/HLT/Trigger/TrigControl/TrigServices/src/HltROBDataProviderSvc.h
@@ -18,6 +18,8 @@
 #include "AthenaBaseComps/AthService.h"
 #include "AthenaKernel/SlotSpecificObj.h"
 #include "AthenaMonitoringKernel/Monitored.h"
+#include "TrigCostMonitorMT/ITrigCostMTSvc.h"
+#include "TrigDataAccessMonitoring/ROBDataMonitor.h"
 
 // STL includes
 #include <string>
@@ -165,6 +167,12 @@ private:
   Gaudi::Property<bool> m_prefetchAllROBsfromROS{
     this, "prefetchAllROBsfromROS", false , "When ROBs from a ROS are requested then prefetch all ROBs in this ROS"};
 
+  Gaudi::Property<bool> m_doCostMonitoring{
+    this, "DoCostMonitoring", true, "Enables start-of-event cost monitoring behavior."};
+
+  ServiceHandle<ITrigCostMTSvc> m_trigCostSvcHandle{ 
+    this, "TrigCostMTSvc", "TrigCostMTSvc", "The trigger cost service" };
+
   /*------------------------+
    * Methods acting on ROBs |
    *------------------------+ 
diff --git a/Trigger/TrigMonitoring/TrigCostMonitorMT/CMakeLists.txt b/Trigger/TrigMonitoring/TrigCostMonitorMT/CMakeLists.txt
index 21d91f2167f84158871d4bf685e20ccdc7d81083..6340548a0b2cb79083743e02c46ee52ecd9d78b4 100644
--- a/Trigger/TrigMonitoring/TrigCostMonitorMT/CMakeLists.txt
+++ b/Trigger/TrigMonitoring/TrigCostMonitorMT/CMakeLists.txt
@@ -12,7 +12,7 @@ atlas_add_library( TrigCostMonitorMTLib
                    TrigCostMonitorMT/*.h
                    src/lib/AlgorithmIdentifier.cxx
                    PUBLIC_HEADERS TrigCostMonitorMT
-                   LINK_LIBRARIES AthenaBaseComps GaudiKernel StoreGateLib xAODTrigger AthViews )
+                   LINK_LIBRARIES AthenaBaseComps GaudiKernel StoreGateLib TrigDataAccessMonitoringLib xAODTrigger AthViews )
 
 atlas_add_component( TrigCostMonitorMT
                      src/*.cxx
diff --git a/Trigger/TrigMonitoring/TrigCostMonitorMT/TrigCostMonitorMT/ITrigCostMTSvc.h b/Trigger/TrigMonitoring/TrigCostMonitorMT/TrigCostMonitorMT/ITrigCostMTSvc.h
index a4017d423285ed70beccade1089cb8af495f036a..a5806b9dff23d87976832ae6b5dfbc77ed42c85e 100644
--- a/Trigger/TrigMonitoring/TrigCostMonitorMT/TrigCostMonitorMT/ITrigCostMTSvc.h
+++ b/Trigger/TrigMonitoring/TrigCostMonitorMT/TrigCostMonitorMT/ITrigCostMTSvc.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
  /*
  */
@@ -12,6 +12,7 @@
 
 #include "xAODTrigger/TrigCompositeContainer.h"
 #include "StoreGate/WriteHandle.h"
+#include "TrigDataAccessMonitoring/ROBDataMonitor.h"
 
 #include <string>
 
@@ -47,12 +48,17 @@ public:
   /**
    * @brief To be used to signal end of an event in a given slot, and to write an output payload to a given handle.
    */
-  virtual StatusCode endEvent(const EventContext&, SG::WriteHandle<xAOD::TrigCompositeContainer>&) = 0; 
+  virtual StatusCode endEvent(const EventContext&, SG::WriteHandle<xAOD::TrigCompositeContainer>&, SG::WriteHandle<xAOD::TrigCompositeContainer>&) = 0; 
 
   /**
    * @brief To be used by external suppliers of data to know if they should spend the CPU to collate their monitoring data
    */
-  virtual bool isMonitoredEvent(const EventContext& context) const = 0;
+  virtual bool isMonitoredEvent(const EventContext& context, const bool includeMultiSlot) const = 0;
+
+  /**
+   * @brief To be used to cache ROBs for ROS
+   */
+  virtual StatusCode monitorROS(const EventContext& context, robmonitor::ROBDataStruct payload) = 0;
 
 };
 
diff --git a/Trigger/TrigMonitoring/TrigCostMonitorMT/src/TrigCostDataStore.h b/Trigger/TrigMonitoring/TrigCostMonitorMT/src/TrigCostDataStore.h
index a2ae233ddbdc05b205db1c487f292f0bfaa026df..426b57b1cb7e20e93aaaf720eaf9a0e358686448 100644
--- a/Trigger/TrigMonitoring/TrigCostMonitorMT/src/TrigCostDataStore.h
+++ b/Trigger/TrigMonitoring/TrigCostMonitorMT/src/TrigCostDataStore.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef TRIGCOSTMONITORMT_TRIGCOSTDATASTORE_H
@@ -52,6 +52,15 @@ class TrigCostDataStore {
    */
   StatusCode insert(const AlgorithmIdentifier& ai, const PAYLOAD& payload);
 
+  /**
+   * @brief Inserts the entry in the vector payload into the map
+   * @param[in] ai The AlgorithmIdentifier to insert for (the key)
+   * @param[in] entry The entry to record
+   * @returns Success unless and class is not initialized, then Failure
+   */
+  template<typename ENTRY>
+  StatusCode push_back(const AlgorithmIdentifier& ai, const ENTRY& entry);
+
   /**
    * @brief Retrieve a payload from the map given an AlgorithmIdentifier
    * @param[in] ai The AlgorithmIdentifier to fetch (the key)
diff --git a/Trigger/TrigMonitoring/TrigCostMonitorMT/src/TrigCostDataStore.icc b/Trigger/TrigMonitoring/TrigCostMonitorMT/src/TrigCostDataStore.icc
index 615552518e99d8c5395847167363bd58d6107018..d3b77b522ff388bceb8c03b83e56d0bbff877a7e 100644
--- a/Trigger/TrigMonitoring/TrigCostMonitorMT/src/TrigCostDataStore.icc
+++ b/Trigger/TrigMonitoring/TrigCostMonitorMT/src/TrigCostDataStore.icc
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #include "AthenaBaseComps/AthCheckMacros.h"
@@ -32,6 +32,25 @@ StatusCode TrigCostDataStore<PAYLOAD>::insert(const AlgorithmIdentifier& ai, con
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 
+template<typename PAYLOAD>
+template<typename ENTRY>
+StatusCode TrigCostDataStore<PAYLOAD>::push_back(const AlgorithmIdentifier& ai, const ENTRY& entry) {
+  MsgStream& msg = *(ai.m_msg);
+  ATH_CHECK( checkSlot(ai.m_slotToSaveInto, msg) );
+  tbb::concurrent_hash_map<AlgorithmIdentifier, std::vector<ENTRY>, AlgorithmIdentifierHashCompare>& mapReference = m_store.at( ai.m_slotToSaveInto );
+  typename tbb::concurrent_hash_map< AlgorithmIdentifier, std::vector<ENTRY>, AlgorithmIdentifierHashCompare>::accessor acc;
+
+  // Adds new value to store entries. If the AI is already there function will return false
+  // and duplicate will not be added. Otherwise new payload will be created
+  // Also obtains write lock on the key value 'name' until 'acc' goes out of scope
+  mapReference.insert(acc, ai);
+  acc->second.push_back(entry);
+
+  return StatusCode::SUCCESS;
+}
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
 template<typename PAYLOAD>
 StatusCode TrigCostDataStore<PAYLOAD>::retrieve(const AlgorithmIdentifier& ai, 
   typename tbb::concurrent_hash_map<AlgorithmIdentifier, PAYLOAD, AlgorithmIdentifierHashCompare>::const_accessor& payload) const
diff --git a/Trigger/TrigMonitoring/TrigCostMonitorMT/src/TrigCostMTSvc.cxx b/Trigger/TrigMonitoring/TrigCostMonitorMT/src/TrigCostMTSvc.cxx
index 22376cf61947ada1626eb19e6d2427eb9baaaa25..7317c3279b425cd70649525c94dd893717696ca1 100644
--- a/Trigger/TrigMonitoring/TrigCostMonitorMT/src/TrigCostMTSvc.cxx
+++ b/Trigger/TrigMonitoring/TrigCostMonitorMT/src/TrigCostMTSvc.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #include "GaudiKernel/ConcurrencyFlags.h"
@@ -56,6 +56,7 @@ StatusCode TrigCostMTSvc::initialize() {
 
   ATH_CHECK(m_algStartInfo.initialize(m_eventSlots));
   ATH_CHECK(m_algStopTime.initialize(m_eventSlots));
+  ATH_CHECK(m_rosData.initialize(m_eventSlots));
 
   return StatusCode::SUCCESS;
 }
@@ -86,6 +87,7 @@ StatusCode TrigCostMTSvc::startEvent(const EventContext& context, const bool ena
       // Empty transient thread-safe stores in preparation for recording this event's cost data
       ATH_CHECK(m_algStartInfo.clear(context, msg()));
       ATH_CHECK(m_algStopTime.clear(context, msg()));
+      ATH_CHECK(m_rosData.clear(context, msg()));
     }
 
     // Enable collection of data in this slot for monitoredEvents
@@ -149,9 +151,11 @@ StatusCode TrigCostMTSvc::monitor(const EventContext& context, const AlgorithmId
     ATH_CHECK( m_algStartInfo.insert(ai, ap) );
 
     // Cache the AlgorithmIdentifier which has just started executing on this thread
-    tbb::concurrent_hash_map<std::thread::id, AlgorithmIdentifier, ThreadHashCompare>::accessor acc;
-    m_threadToAlgMap.insert(acc, ap.m_algThreadID);
-    acc->second = ai;
+    if (ai.m_realSlot == ai.m_slotToSaveInto) {
+      tbb::concurrent_hash_map<std::thread::id, AlgorithmIdentifier, ThreadHashCompare>::accessor acc;
+      m_threadToAlgMap.insert(acc, ap.m_algThreadID);
+      acc->second = ai;
+    }
 
   } else if (type == AuditType::After) {
 
@@ -170,7 +174,28 @@ StatusCode TrigCostMTSvc::monitor(const EventContext& context, const AlgorithmId
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 
-StatusCode TrigCostMTSvc::endEvent(const EventContext& context, SG::WriteHandle<xAOD::TrigCompositeContainer>& outputHandle) { 
+StatusCode TrigCostMTSvc::monitorROS(const EventContext& /*context*/, robmonitor::ROBDataStruct payload){
+  ATH_MSG_DEBUG( "Received ROB payload " << payload );
+
+  // Associate payload with an algorithm
+  AlgorithmIdentifier theAlg;
+  {
+    tbb::concurrent_hash_map<std::thread::id, AlgorithmIdentifier, ThreadHashCompare>::const_accessor acc;
+    ATH_CHECK( m_threadToAlgMap.find(acc, std::this_thread::get_id()) );
+    theAlg = acc->second;
+  }
+
+  // Record data in TrigCostDataStore
+  ATH_MSG_DEBUG( "Adding " << payload.rob_id << " to " << theAlg.m_hash );
+  ATH_CHECK( m_rosData.push_back(theAlg, payload) );
+
+  return StatusCode::SUCCESS;
+}
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+StatusCode TrigCostMTSvc::endEvent(const EventContext& context, SG::WriteHandle<xAOD::TrigCompositeContainer>& costOutputHandle, SG::WriteHandle<xAOD::TrigCompositeContainer>& rosOutputHandle) { 
   ATH_CHECK(checkSlot(context));
   if (m_eventMonitored[ context.slot() ] == false) {
     // This event was not monitored - nothing to do.
@@ -228,6 +253,7 @@ StatusCode TrigCostMTSvc::endEvent(const EventContext& context, SG::WriteHandle<
 
   ATH_MSG_DEBUG("Monitored event with " << std::distance(beginIt, endIt) << " AlgorithmPayload objects.");
 
+  std::map<size_t, size_t> aiToHandleIndex;
   for (it = beginIt; it != endIt; ++it) {
     const AlgorithmIdentifier& ai = it->first;
     const AlgorithmPayload& ap = it->second;
@@ -284,7 +310,7 @@ StatusCode TrigCostMTSvc::endEvent(const EventContext& context, SG::WriteHandle<
 
     // Make a new TrigComposite to persist monitoring payload for this alg
     xAOD::TrigComposite* tc = new xAOD::TrigComposite();
-    outputHandle->push_back( tc ); 
+    costOutputHandle->push_back( tc ); 
     // tc is now owned by storegate and, and has an aux store provided by the TrigCompositeCollection
 
     const uint32_t threadID = static_cast<uint32_t>( std::hash< std::thread::id >()(ap.m_algThreadID) );
@@ -312,11 +338,34 @@ StatusCode TrigCostMTSvc::endEvent(const EventContext& context, SG::WriteHandle<
     result &= tc->setDetail("start", startTime);
     result &= tc->setDetail("stop", stopTime);
     if (!result) ATH_MSG_WARNING("Failed to append one or more details to trigger cost TC");
+
+    aiToHandleIndex[ai.m_hash] = costOutputHandle->size() - 1;
+  }
+
+  typedef tbb::concurrent_hash_map< AlgorithmIdentifier, std::vector<robmonitor::ROBDataStruct>, AlgorithmIdentifierHashCompare>::const_iterator ROBConstIt;
+  ROBConstIt beginRob;
+  ROBConstIt endRob;
+  
+  ATH_CHECK(m_rosData.getIterators(context, msg(), beginRob, endRob));
+  
+  for (ROBConstIt it = beginRob; it != endRob; ++it) {
+    // TrigComposite for ROS caching
+    xAOD::TrigComposite* tcr = new xAOD::TrigComposite();
+    rosOutputHandle->push_back( tcr ); 
+
+    size_t aiHash = it->first.m_hash;
+    if (aiToHandleIndex.count(aiHash) == 0) {
+      ATH_MSG_WARNING("Algorithm with hash " << TrigConf::HLTUtils::hash2string( aiHash, "ALG") << " not found!");
+    }
+
+    bool result = true;
+    result &= tcr->setDetail("alg_idx", aiToHandleIndex[aiHash]);
+    if (!result) ATH_MSG_WARNING("Failed to append one or more details to trigger cost ROS TC");
   }
 
   if (msg().level() <= MSG::VERBOSE) {
     ATH_MSG_VERBOSE("--- Trig Cost Event Summary ---");
-    for ( const xAOD::TrigComposite* tc : *outputHandle ) {
+    for ( const xAOD::TrigComposite* tc : *costOutputHandle ) {
       ATH_MSG_VERBOSE("Algorithm:'" << TrigConf::HLTUtils::hash2string( tc->getDetail<TrigConf::HLTHash>("alg"), "ALG") << "'");
       ATH_MSG_VERBOSE("  Store:'" << TrigConf::HLTUtils::hash2string( tc->getDetail<TrigConf::HLTHash>("store"), "STORE") << "'");
       ATH_MSG_VERBOSE("  View ID:" << tc->getDetail<int16_t>("view"));
@@ -354,11 +403,11 @@ int32_t TrigCostMTSvc::getROIID(const EventContext& context) {
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 
-bool TrigCostMTSvc::isMonitoredEvent(const EventContext& context) const {
+bool TrigCostMTSvc::isMonitoredEvent(const EventContext& context, const bool includeMultiSlot) const {
   if (m_eventMonitored[ context.slot() ]) {
     return true;
   }
-  if (m_enableMultiSlot) {
+  if (includeMultiSlot && m_enableMultiSlot) {
     return m_eventMonitored[ m_masterSlot ];
   }
   return false;
diff --git a/Trigger/TrigMonitoring/TrigCostMonitorMT/src/TrigCostMTSvc.h b/Trigger/TrigMonitoring/TrigCostMonitorMT/src/TrigCostMTSvc.h
index c4dbb7ea58650e30901000a4e8f31f2f247dc613..6cc891368f65a61db676b300ea36ffddcab2b5e8 100644
--- a/Trigger/TrigMonitoring/TrigCostMonitorMT/src/TrigCostMTSvc.h
+++ b/Trigger/TrigMonitoring/TrigCostMonitorMT/src/TrigCostMTSvc.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef TRIGCOSTMONITORMT_TRIGCOSTMTSVC_H
@@ -8,6 +8,7 @@
 #include <atomic>
 #include <shared_mutex>
 #include <thread>
+#include <vector>
 
 #include "GaudiKernel/ToolHandle.h"
 
@@ -76,15 +77,23 @@ class TrigCostMTSvc : public extends <AthService, ITrigCostMTSvc> {
   /**
    * @brief Implementation of ITrigCostMTSvc::endEvent.
    * @param[in] context The event context
-   * @param[out] outputHandle Write handle to fill with execution summary if the event was monitored
+   * @param[out] costOutputHandle Write handle to fill with execution summary if the event was monitored
+   * @param[out] rosOutputHandle Write handle to fill with ROS requests summary if the event was monitored
    */
-  virtual StatusCode endEvent(const EventContext& context, SG::WriteHandle<xAOD::TrigCompositeContainer>& outputHandle) override; 
+  virtual StatusCode endEvent(const EventContext& context, SG::WriteHandle<xAOD::TrigCompositeContainer>& costOutputHandle, SG::WriteHandle<xAOD::TrigCompositeContainer>& rosOutputHandle) override; 
 
   /**
    * @return If the current context is flagged as being monitored. 
    * @param[in] context The event context
    */
-  virtual bool isMonitoredEvent(const EventContext& context) const override;
+  virtual bool isMonitoredEvent(const EventContext& context, const bool includeMultiSlot = true) const override;
+
+  /**
+   * @brief Implementation of ITrigCostMTSvc::monitorROS.
+   * @param[in] context The event context
+   * @param[in] payload ROB data to be associated with ROS
+   */
+  virtual StatusCode monitorROS(const EventContext& context, robmonitor::ROBDataStruct payload) override;
 
   private: 
 
@@ -127,12 +136,14 @@ class TrigCostMTSvc : public extends <AthService, ITrigCostMTSvc> {
   std::mutex m_globalMutex; //!< Used to protect all-slot modifications.
   TrigCostDataStore<AlgorithmPayload> m_algStartInfo; //!< Thread-safe store of algorithm start payload.
   TrigCostDataStore<TrigTimeStamp> m_algStopTime; //!< Thread-safe store of algorithm stop times.
+  TrigCostDataStore<std::vector<robmonitor::ROBDataStruct>> m_rosData; //!< Thread-safe store of ROS data
 
   tbb::concurrent_hash_map<std::thread::id, AlgorithmIdentifier, ThreadHashCompare> m_threadToAlgMap; //!< Keeps track of what is running right now in each thread.
 
   std::unordered_map<uint32_t, uint32_t> m_threadToCounterMap; //!< Map thread's hash ID to a counting numeral
   size_t m_threadCounter; //!< Count how many unique thread ID we have seen 
 
+
   Gaudi::Property<bool>        m_monitorAllEvents{this, "MonitorAllEvents", false, "Monitor every HLT event, e.g. for offline validation."};
   Gaudi::Property<bool>        m_enableMultiSlot{this, "EnableMultiSlot", true, "Monitored events in the MasterSlot collect data from events running in other slots."};
   Gaudi::Property<bool>        m_saveHashes{this, "SaveHashes", false, "Store a copy of the hash dictionary for easier debugging"};
diff --git a/Trigger/TrigSteer/TrigOutputHandling/src/DecisionSummaryMakerAlg.cxx b/Trigger/TrigSteer/TrigOutputHandling/src/DecisionSummaryMakerAlg.cxx
index 0dd30a96a50a8a881dea6a228dfdd2c58bedd6fb..531fc13566e0b564d5535f04dadb3fc095bc84f3 100644
--- a/Trigger/TrigSteer/TrigOutputHandling/src/DecisionSummaryMakerAlg.cxx
+++ b/Trigger/TrigSteer/TrigOutputHandling/src/DecisionSummaryMakerAlg.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 #include "TrigCompositeUtils/HLTIdentifier.h"
 #include "DecisionSummaryMakerAlg.h"
@@ -22,6 +22,7 @@ StatusCode DecisionSummaryMakerAlg::initialize() {
   }
 
   ATH_CHECK( m_costWriteHandleKey.initialize( m_doCostMonitoring ) );
+  ATH_CHECK( m_rosWriteHandleKey.initialize( m_doCostMonitoring ) );
   if (m_doCostMonitoring) {
     ATH_CHECK( m_trigCostSvcHandle.retrieve() );
   }
@@ -138,8 +139,9 @@ StatusCode DecisionSummaryMakerAlg::execute(const EventContext& context) const {
   // Do cost monitoring
   if (m_doCostMonitoring) {
     SG::WriteHandle<xAOD::TrigCompositeContainer> costMonOutput = createAndStore(m_costWriteHandleKey, context);
+    SG::WriteHandle<xAOD::TrigCompositeContainer> rosMonOutput = createAndStore(m_rosWriteHandleKey, context);
     // Populate collection (assuming monitored event, otherwise collection will remain empty)
-    ATH_CHECK(m_trigCostSvcHandle->endEvent(context, costMonOutput));
+    ATH_CHECK(m_trigCostSvcHandle->endEvent(context, costMonOutput, rosMonOutput));
   }
 
   // Set the algorithm's filter status. This controlls the running of finalisation algs which we only want to execute
diff --git a/Trigger/TrigSteer/TrigOutputHandling/src/DecisionSummaryMakerAlg.h b/Trigger/TrigSteer/TrigOutputHandling/src/DecisionSummaryMakerAlg.h
index 96e4bd9b4b76dbff314c16c228e59bb6debc0eaf..7b050aac8d3af106f434f9095a3cf0689823902c 100644
--- a/Trigger/TrigSteer/TrigOutputHandling/src/DecisionSummaryMakerAlg.h
+++ b/Trigger/TrigSteer/TrigOutputHandling/src/DecisionSummaryMakerAlg.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 #ifndef TRIGOUTPUTHANDLING_DECISIONSUMMARYMAKERALG_H
 #define TRIGOUTPUTHANDLING_DECISIONSUMMARYMAKERALG_H
@@ -35,6 +35,9 @@ private:
   SG::WriteHandleKey<xAOD::TrigCompositeContainer> m_costWriteHandleKey { this, "CostWriteHandleKey", "HLT_TrigCostContainer",
     "TrigComposite collections summarising the HLT execution" };
 
+  SG::WriteHandleKey<xAOD::TrigCompositeContainer> m_rosWriteHandleKey { this, "ROSWriteHandleKey", "HLT_TrigCostROSContainer",
+    "TrigComposite collections summarising the ROS requests" };
+
   SG::ReadHandleKey<xAOD::TrigCompositeContainer> m_l1SummaryKey { this, "L1DecoderSummaryKey", "L1DecoderSummary",
     "Chains status after L1 and prescaling" };
 
diff --git a/Trigger/TriggerCommon/TrigEDMConfig/python/TriggerEDMRun3.py b/Trigger/TriggerCommon/TrigEDMConfig/python/TriggerEDMRun3.py
index 5a58b88f36b603abb09d32bdc46554787a3d7b08..89ba6f1e84fdbf4a4b3b039cf2b1cdc568f133c4 100644
--- a/Trigger/TriggerCommon/TrigEDMConfig/python/TriggerEDMRun3.py
+++ b/Trigger/TriggerCommon/TrigEDMConfig/python/TriggerEDMRun3.py
@@ -96,6 +96,8 @@ TriggerHLTListRun3 = [
 
     ('xAOD::TrigCompositeContainer#HLT_TrigCostContainer',   'CostMonDS ESD', 'Steer'),
     ('xAOD::TrigCompositeAuxContainer#HLT_TrigCostContainerAux.alg.store.view.thread.thash.slot.roi.start.stop', 'CostMonDS ESD', 'Steer'),
+    ('xAOD::TrigCompositeContainer#HLT_TrigCostROSContainer',   'CostMonDS ESD', 'Steer'),
+    ('xAOD::TrigCompositeAuxContainer#HLT_TrigCostROSContainerAux.alg_idx', 'CostMonDS ESD', 'Steer'),
 
     # Run-2 L1 (temporary)
     ('xAOD::MuonRoIContainer#LVL1MuonRoIs' ,                 'ESD AODFULL AODSLIM AODVERYSLIM AODBLSSLIM', 'L1'),