diff --git a/Trigger/TrigSteer/TrigOutputHandling/src/HLTEDMCreator.cxx b/Trigger/TrigSteer/TrigOutputHandling/src/HLTEDMCreator.cxx
index 3ed868eafa53b9f6a230eee2f750b2dbf4ced8ff..8c10a3990c7056317fde6e63aaacee7e21dc808a 100644
--- a/Trigger/TrigSteer/TrigOutputHandling/src/HLTEDMCreator.cxx
+++ b/Trigger/TrigSteer/TrigOutputHandling/src/HLTEDMCreator.cxx
@@ -1,6 +1,6 @@
 
 /*
-  Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
 */
 
 
@@ -263,7 +263,7 @@ StatusCode  HLTEDMCreator::viewsMerge( ViewContainer const& views, const SG::Rea
 }
 
  
-StatusCode HLTEDMCreator::fixLinks() const {
+StatusCode HLTEDMCreator::fixLinks( EventContext const& context ) const {
   if ( m_fixLinks.value().empty() ) {
     ATH_MSG_DEBUG("fixLinks: No collections defined for this tool");
     return StatusCode::SUCCESS;
@@ -273,6 +273,11 @@ StatusCode HLTEDMCreator::fixLinks() const {
 
   // Do the remapping
   int writeHandleArrayIndex = -1;
+
+  // Create a HandleKey that we can re-use during the loop (slightly better performance)
+  SG::ReadHandleKey<xAOD::TrigCompositeContainer> readHandleKey("temp");
+  ATH_CHECK( readHandleKey.initialize() );
+
   for ( const auto& writeHandleKey: m_TrigCompositeContainer ) {
     // Check if we are re-mapping this handle
     const bool doFixLinks = std::any_of(m_fixLinks.begin(), m_fixLinks.end(), [&](const std::string& s) { return s == writeHandleKey.key(); } );
@@ -285,17 +290,21 @@ StatusCode HLTEDMCreator::fixLinks() const {
     ++writeHandleArrayIndex;
 
     ATH_MSG_DEBUG("Fixing links: confirm collection is there: " << writeHandleKey.key() << ", write handle array index: " << writeHandleArrayIndex);
-    SG::ReadHandle<xAOD::TrigCompositeContainer> readHandle( writeHandleKey.key() );
+    // Update key name
+    readHandleKey = writeHandleKey.key();
+    auto readHandle = SG::makeHandle(readHandleKey, context);
     if ( not readHandle.isValid() ) { // object missing, this is now an error as we should have literally just created it
-      ATH_MSG_ERROR("  Collection is not present. " << writeHandleKey.key() << " should have been created by createIfMissing.");
+      ATH_MSG_ERROR("Collection is not present. " << readHandleKey.key() << " should have been created by createIfMissing.");
       return StatusCode::FAILURE;
     }
 
     ATH_MSG_DEBUG("Collection exists with size " << readHandle->size() << " Decision objects" );
     ATH_MSG_DEBUG("Adding decorations: " << m_remapLinkColKeys.at( writeHandleArrayIndex ).key() << " and " << m_remapLinkColIndices.at( writeHandleArrayIndex ).key() );
     
-    SG::WriteDecorHandle<xAOD::TrigCompositeContainer, std::vector<SG::sgkey_t> > keyDecor( m_remapLinkColKeys.at( writeHandleArrayIndex ) );
-    SG::WriteDecorHandle<xAOD::TrigCompositeContainer, std::vector<xAOD::TrigComposite::index_type> > indexDecor( m_remapLinkColIndices.at( writeHandleArrayIndex ) );
+    SG::WriteDecorHandle<xAOD::TrigCompositeContainer, std::vector<SG::sgkey_t> >
+      keyDecor(m_remapLinkColKeys.at( writeHandleArrayIndex ), context );
+    SG::WriteDecorHandle<xAOD::TrigCompositeContainer, std::vector<xAOD::TrigComposite::index_type> >
+      indexDecor( m_remapLinkColIndices.at( writeHandleArrayIndex ), context );
 
     // Examine each input TC
     int decisionObjectIndex = -1;
@@ -349,15 +358,26 @@ StatusCode HLTEDMCreator::fixLinks() const {
 template<typename T, typename STORE, typename G, typename M>
 StatusCode HLTEDMCreator::createIfMissing( const EventContext& context, const ConstHandlesGroup<T>& handles, G& generator, M merger ) const {
 
+  // Declare a ReadHandleKey that we can re-use during the loop for reading.
+  SG::ReadHandleKey<T> rhk("temp");
+
+  // Same for the Aux store. If there is none (void) this would not compile
+  // so we just define a dummy RHK, which will never be used, of type T again.
+  using AuxType = std::conditional_t<std::is_void_v<STORE>, T, STORE>;
+  SG::ReadHandleKey<AuxType> rhkAux("temp");
+
+  ATH_CHECK( rhk.initialize() && rhkAux.initialize() );
+
   for (size_t i = 0; i < handles.out.size(); ++i) {
-    SG::WriteHandleKey<T> writeHandleKey = handles.out.at(i);
+    const SG::WriteHandleKey<T>& whk = handles.out.at(i);
+    rhk = whk.key();  // set the RHK to the same key as the WHK
 
     if ( handles.views.empty() ) { // no merging will be needed
       // Note: This is correct. We are testing if we can read, and if we cannot then we write.
       // What we write will either be a dummy (empty) container, or be populated from N in-View collections.
-      SG::ReadHandle<T> readHandle( writeHandleKey.key() );
+      auto readHandle = SG::makeHandle( rhk, context );
       if ( readHandle.isValid() ) {
-        ATH_MSG_VERBOSE( writeHandleKey.key() << " is already present" );
+        ATH_MSG_VERBOSE( rhk.key() << " is already present" );
         generator.create(false, false);
 
         // For xAOD types we need to ensure there is an Aux store. This can happen if the
@@ -365,15 +385,17 @@ StatusCode HLTEDMCreator::createIfMissing( const EventContext& context, const Co
         // The TriggerEDMDeserialiserAlg will already have created a DataLink to the Aux store
         // for the interface container. Now we just need to create an empty Aux store.
         if constexpr (!std::is_void_v<STORE>) {
-          SG::ReadHandle<STORE> readAuxHandle( writeHandleKey.key() + "Aux." );
+          rhkAux = rhk.key() + "Aux.";
+          auto readAuxHandle = SG::makeHandle(rhkAux, context);
           if ( !readAuxHandle.isValid() ) {
-            SG::WriteHandle<STORE> writeAuxHandle( writeHandleKey.key() + "Aux." );
-            ATH_MSG_DEBUG("Creating missing Aux store for " << writeHandleKey.key());
+            // This is rare so we just create a WH as needed:
+            SG::WriteHandle<STORE> writeAuxHandle( rhkAux.key(), context );
+            ATH_MSG_DEBUG("Creating missing Aux store for " << rhk.key());
             ATH_CHECK( writeAuxHandle.record(std::make_unique<STORE>()) );
           }
         }
       } else {
-        ATH_MSG_DEBUG( writeHandleKey.key() << " is missing, creating it" );
+        ATH_MSG_DEBUG( rhk.key() << " is missing, creating it" );
         generator.create(true, true);
       }
 
@@ -388,28 +410,27 @@ StatusCode HLTEDMCreator::createIfMissing( const EventContext& context, const Co
       if ( handles.out.size() == 1  ) {
       	generator.create(true, true);
       } else  {
-        const bool doCreate = i == 0 or handles.out.at(i-1).key() != handles.out.at(i).key();
-        const bool doRecord = i == handles.out.size()-1 or handles.out.at(i+1).key() != handles.out.at(i).key();
+        const bool doCreate = i == 0 or handles.out.at(i-1).key() != whk.key();
+        const bool doRecord = i == handles.out.size()-1 or handles.out.at(i+1).key() != whk.key();
         ATH_MSG_DEBUG( "Instructing generator " <<  (doCreate ? "to" : "NOT TO") <<  " create collection and " << (doRecord ? "to" : "NOT TO") << " record collection in this iteration");
         generator.create(doCreate, doRecord);
       }
 
-      SG::ReadHandleKey<ViewContainer> viewsReadHandleKey = handles.views.at(i);
+      const SG::ReadHandleKey<ViewContainer>& viewsReadHandleKey = handles.views.at(i);
       ATH_MSG_DEBUG("Will be trying to merge from the " << viewsReadHandleKey.key() << " view container into that output");
 
       auto viewsHandle = SG::makeHandle( viewsReadHandleKey, context );
       if ( viewsHandle.isValid() ) {
-        SG::ReadHandleKey<T> inViewReadHandleKey = handles.in.at(i);
+        const SG::ReadHandleKey<T>& inViewReadHandleKey = handles.in.at(i);
         ATH_MSG_DEBUG("Will be merging from " << viewsHandle->size() << " views using in-view key " << inViewReadHandleKey.key() );
         ATH_CHECK( (this->*merger)( *viewsHandle, inViewReadHandleKey , context, *generator.data.get() ) );
       } else {
-        ATH_MSG_DEBUG("Views " << viewsReadHandleKey.key() << " are missing. Will leave " << writeHandleKey.key() << " output collection empty.");
+        ATH_MSG_DEBUG("Views " << viewsReadHandleKey.key() << " are missing. Will leave " << whk.key() << " output collection empty.");
       }
 
       // Also consider probe variants of each EventView.
       // Not every container will have a corresponding set of (typically) lower-pT probe ROIs, but it's safer to always test.
-      static const std::string probe_suffix = "_probe";
-      const std::string viewsReadHandleKeyProbe = viewsReadHandleKey.key() + probe_suffix;
+      const std::string viewsReadHandleKeyProbe = viewsReadHandleKey.key() + "_probe";
       ATH_MSG_VERBOSE("Will try to merge from the " << viewsReadHandleKeyProbe <<  " view container into that output");
 
       // Falling back to direct SG access here to avoid uninitiated key errors. This is safe to do in the context of the Trigger ControlFlow.
@@ -419,7 +440,7 @@ StatusCode HLTEDMCreator::createIfMissing( const EventContext& context, const Co
         ATH_CHECK(evtStore()->retrieve(viewsContainer_probe, viewsReadHandleKeyProbe));
       }
       if ( viewsContainer_probe ) {
-        SG::ReadHandleKey<T> inViewReadHandleKey = handles.in.at(i);
+        const SG::ReadHandleKey<T>& inViewReadHandleKey = handles.in.at(i);
         ATH_MSG_DEBUG("Will be merging from " << viewsContainer_probe->size() << " probe views using in-view key " << inViewReadHandleKey.key() );
         ATH_CHECK( (this->*merger)( *viewsContainer_probe, inViewReadHandleKey , context, *generator.data.get() ) );
       } else {
@@ -428,7 +449,7 @@ StatusCode HLTEDMCreator::createIfMissing( const EventContext& context, const Co
 
     }
 
-    auto writeHandle = SG::makeHandle( writeHandleKey, context );
+    auto writeHandle = SG::makeHandle( whk, context );
     ATH_CHECK( generator.record( writeHandle ) );
   }
 
@@ -505,7 +526,7 @@ StatusCode HLTEDMCreator::createOutput(const EventContext& context) const {
   CREATE_XAOD( MuonRoIContainer, MuonRoIAuxContainer );
 
   // After view collections are merged, need to update collection links
-  ATH_CHECK( fixLinks() );
+  ATH_CHECK( fixLinks(context) );
   
 #undef CREATE_XAOD
 
diff --git a/Trigger/TrigSteer/TrigOutputHandling/src/HLTEDMCreator.h b/Trigger/TrigSteer/TrigOutputHandling/src/HLTEDMCreator.h
index 833a93bebba449397024fec9bada6fbf48498f1d..3d4b6740b3ac4ab5408d1aacd9e29f9ed4491a91 100644
--- a/Trigger/TrigSteer/TrigOutputHandling/src/HLTEDMCreator.h
+++ b/Trigger/TrigSteer/TrigOutputHandling/src/HLTEDMCreator.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
 */
 #ifndef TRIGOUTPUTHANDLING_HLTEDMCREATOR_H
 #define TRIGOUTPUTHANDLING_HLTEDMCREATOR_H 1
@@ -223,7 +223,7 @@ class HLTEDMCreator: public extends<AthAlgTool, IHLTOutputTool>  {
     const SG::ReadHandleKeyArray< ViewContainer >& views;
   };
 
-  StatusCode fixLinks() const;
+  StatusCode fixLinks( EventContext const& context ) const;
 
   template<typename T, typename STORE, typename G, typename M >
     StatusCode createIfMissing( const EventContext& context, const ConstHandlesGroup<T>& handles,