diff --git a/Event/TrackEvent/Event/PrFittedForwardTracks.h b/Event/TrackEvent/Event/PrFittedForwardTracks.h
index e83aec099e1db3fccaaaa740a8a44bf2dc83a385..9164e428bb1796120d38c196cc75d2404e0847ef 100644
--- a/Event/TrackEvent/Event/PrFittedForwardTracks.h
+++ b/Event/TrackEvent/Event/PrFittedForwardTracks.h
@@ -12,11 +12,10 @@
 #pragma once
 #include "Event/PrForwardTracks.h"
 #include "Event/PrVeloHits.h"
-
+#include "Kernel/EventLocalAllocator.h"
 #include "Kernel/LHCbID.h"
 #include "LHCbMath/SIMDWrapper.h"
 #include "LHCbMath/Vec3.h"
-
 #include "SOAExtensions/ZipUtils.h"
 
 /**
@@ -27,35 +26,42 @@
 
 namespace LHCb::Pr::Fitted::Forward {
   class Tracks {
-    constexpr static int max_tracks = align_size( 1024 );
+    constexpr static int         max_tracks = align_size( 1024 );
+    constexpr static int         row_size   = 15;
+    constexpr static std::size_t array_size = max_tracks * row_size;
+    using data_t                            = union {
+      float f;
+      int   i;
+    };
 
   public:
+    using allocator_type = LHCb::Allocators::EventLocal<data_t>;
     Tracks( Pr::Forward::Tracks const* forward_ancestors,
-            Zipping::ZipFamilyNumber   zipIdentifier = Zipping::generateZipIdentifier() )
-        : m_forward_ancestors{forward_ancestors}, m_zipIdentifier{zipIdentifier} {
-      const size_t size = max_tracks * 15;
-      m_data            = static_cast<data_t*>( std::aligned_alloc( 64, size * sizeof( int ) ) );
-      ;
-    }
+            Zipping::ZipFamilyNumber zipIdentifier = Zipping::generateZipIdentifier(), allocator_type alloc = {} )
+        : m_alloc{std::move( alloc )}
+        , m_data{std::allocator_traits<allocator_type>::allocate( m_alloc, array_size )}
+        , m_forward_ancestors{forward_ancestors}
+        , m_zipIdentifier{zipIdentifier} {}
 
     // Special constructor for zipping machinery
     Tracks( Zipping::ZipFamilyNumber zipIdentifier, Tracks const& tracks )
-        : Tracks( tracks.getForwardAncestors(), zipIdentifier ) {}
+        : Tracks( tracks.getForwardAncestors(), zipIdentifier, tracks.m_alloc ) {}
 
     Tracks( const Tracks& ) = delete;
 
     Tracks( Tracks&& other )
-        : m_data{std::exchange( other.m_data, nullptr )}
+        : m_alloc{std::move( other.m_alloc )}
+        , m_data{std::exchange( other.m_data, nullptr )}
         , m_size{other.m_size}
         , m_forward_ancestors{other.m_forward_ancestors}
         , m_zipIdentifier{other.m_zipIdentifier} {}
 
-    [[nodiscard]] bool                     empty() const { return m_size == 0; }
-    [[nodiscard]] inline int               size() const { return m_size; }
-    inline int&                            size() { return m_size; }
-    [[nodiscard]] Zipping::ZipFamilyNumber zipIdentifier() const { return m_zipIdentifier; }
-
-    [[nodiscard]] Pr::Forward::Tracks const* getForwardAncestors() const { return m_forward_ancestors; };
+    [[nodiscard]] allocator_type             get_allocator() const noexcept { return m_alloc; }
+    [[nodiscard]] bool                       empty() const noexcept { return m_size == 0; }
+    [[nodiscard]] int                        size() const noexcept { return m_size; }
+    int&                                     size() noexcept { return m_size; }
+    [[nodiscard]] Zipping::ZipFamilyNumber   zipIdentifier() const noexcept { return m_zipIdentifier; }
+    [[nodiscard]] Pr::Forward::Tracks const* getForwardAncestors() const noexcept { return m_forward_ancestors; };
 
     // Index in TracksFT container of the track's ancestor
     SOA_ACCESSOR( trackFT, &( m_data->i ) )
@@ -154,16 +160,13 @@ namespace LHCb::Pr::Fitted::Forward {
       return nHits;
     }
 
-    ~Tracks() { std::free( m_data ); }
+    ~Tracks() { std::allocator_traits<allocator_type>::deallocate( m_alloc, m_data, array_size ); }
 
   private:
-    using data_t = union {
-      float f;
-      int   i;
-    };
-    alignas( 64 ) data_t* m_data;
-    int                        m_size              = 0;
-    Pr::Forward::Tracks const* m_forward_ancestors = nullptr;
+    allocator_type             m_alloc;
+    data_t*                    m_data;
+    int                        m_size{0};
+    Pr::Forward::Tracks const* m_forward_ancestors{nullptr};
     Zipping::ZipFamilyNumber   m_zipIdentifier;
   };
 } // namespace LHCb::Pr::Fitted::Forward
diff --git a/Event/TrackEvent/Event/PrForwardTracks.h b/Event/TrackEvent/Event/PrForwardTracks.h
index d6032a0e3a6a4e9613a73c177783512a236c5be6..1595be1ca51c17012ea776e260717799f2174119 100644
--- a/Event/TrackEvent/Event/PrForwardTracks.h
+++ b/Event/TrackEvent/Event/PrForwardTracks.h
@@ -12,11 +12,9 @@
 #pragma once
 #include "Event/PrUpstreamTracks.h"
 #include "Event/PrVeloTracks.h"
-
+#include "Kernel/EventLocalAllocator.h"
 #include "LHCbMath/SIMDWrapper.h"
 #include "LHCbMath/Vec3.h"
-#include <iostream>
-
 #include "SOAExtensions/ZipUtils.h"
 
 /**
@@ -29,31 +27,40 @@ namespace LHCb::Pr::Forward {
   class Tracks {
 
   public:
-    constexpr static int max_tracks = align_size( 1024 );
-    constexpr static int max_hits   = 40;
-
+    constexpr static int         max_tracks = align_size( 1024 );
+    constexpr static int         max_hits   = 40;
+    constexpr static int         row_size   = max_hits + 9;
+    constexpr static std::size_t array_size = max_tracks * row_size;
+    using data_t                            = union {
+      float f;
+      int   i;
+    };
+    using allocator_type = LHCb::Allocators::EventLocal<data_t>;
     Tracks( Velo::Tracks const* velo_ancestors, Upstream::Tracks const* upstream_ancestors,
-            Zipping::ZipFamilyNumber zipIdentifier = Zipping::generateZipIdentifier() )
-        : m_velo_ancestors{velo_ancestors}, m_upstream_ancestors{upstream_ancestors}, m_zipIdentifier{zipIdentifier} {
-      const size_t size = max_tracks * ( max_hits + 9 );
-      m_data            = static_cast<data_t*>( std::aligned_alloc( 64, size * sizeof( int ) ) );
-    }
+            Zipping::ZipFamilyNumber zipIdentifier = Zipping::generateZipIdentifier(), allocator_type alloc = {} )
+        : m_alloc{std::move( alloc )}
+        , m_data{std::allocator_traits<allocator_type>::allocate( m_alloc, array_size )}
+        , m_velo_ancestors{velo_ancestors}
+        , m_upstream_ancestors{upstream_ancestors}
+        , m_zipIdentifier{zipIdentifier} {}
 
     // Special constructor for zipping machinery
     Tracks( Zipping::ZipFamilyNumber zipIdentifier, Tracks const& tracks )
-        : Tracks( tracks.getVeloAncestors(), tracks.getUpstreamAncestors(), zipIdentifier ) {}
+        : Tracks( tracks.getVeloAncestors(), tracks.getUpstreamAncestors(), zipIdentifier, tracks.m_alloc ) {}
 
     Tracks( const Tracks& ) = delete;
 
     Tracks( Tracks&& other )
-        : m_data{std::exchange( other.m_data, nullptr )}
+        : m_alloc{std::move( other.m_alloc )}
+        , m_data{std::exchange( other.m_data, nullptr )}
         , m_size{other.m_size}
         , m_velo_ancestors{other.m_velo_ancestors}
         , m_upstream_ancestors{other.m_upstream_ancestors}
         , m_zipIdentifier{other.m_zipIdentifier} {}
 
-    [[nodiscard]] int size() const { return m_size; }
-    int&              size() { return m_size; }
+    [[nodiscard]] allocator_type get_allocator() const noexcept { return m_alloc; }
+    [[nodiscard]] int            size() const { return m_size; }
+    int&                         size() { return m_size; }
 
     // Return pointer to ancestor container
     [[nodiscard]] Velo::Tracks const*     getVeloAncestors() const { return m_velo_ancestors; };
@@ -113,17 +120,14 @@ namespace LHCb::Pr::Forward {
       return ids;
     }
 
-    ~Tracks() { std::free( m_data ); }
+    ~Tracks() { std::allocator_traits<allocator_type>::deallocate( m_alloc, m_data, array_size ); }
 
   private:
-    using data_t = union {
-      float f;
-      int   i;
-    };
-    alignas( 64 ) data_t* m_data;
-    int                      m_size               = 0;
-    Velo::Tracks const*      m_velo_ancestors     = nullptr;
-    Upstream::Tracks const*  m_upstream_ancestors = nullptr;
+    allocator_type           m_alloc;
+    data_t*                  m_data{nullptr};
+    int                      m_size{0};
+    Velo::Tracks const*      m_velo_ancestors{nullptr};
+    Upstream::Tracks const*  m_upstream_ancestors{nullptr};
     Zipping::ZipFamilyNumber m_zipIdentifier;
   };
 } // namespace LHCb::Pr::Forward
diff --git a/FT/FTDAQ/src/FTRawBankDecoder.cpp b/FT/FTDAQ/src/FTRawBankDecoder.cpp
index 8934a75d46a9c64afc9bce1e9cbb982476e5a37b..2ee87002767fa8bb4178b78c0a6eeb26e08b50ca 100644
--- a/FT/FTDAQ/src/FTRawBankDecoder.cpp
+++ b/FT/FTDAQ/src/FTRawBankDecoder.cpp
@@ -94,8 +94,9 @@ FTRawBankDecoder::FTRawBankDecoder( const std::string& name, ISvcLocator* pSvcLo
 }
 
 template <>
-FTLiteClusters FTRawBankDecoder::decode<6>( LHCb::span<const LHCb::RawBank*> banks, unsigned int nClusters ) const {
-  FTLiteClusters clus{nClusters};
+FTLiteClusters FTRawBankDecoder::decode<6>( const EventContext& evtCtx, LHCb::span<const LHCb::RawBank*> banks,
+                                            unsigned int nClusters ) const {
+  FTLiteClusters clus{nClusters, LHCb::getMemResource( evtCtx )};
   for ( const LHCb::RawBank* bank : banks ) { // Iterates over the banks
     LHCb::FTChannelID offset  = m_readoutTool->channelIDShift( bank->sourceID() );
     auto              quarter = quarterFromChannel( offset );
@@ -167,8 +168,9 @@ FTLiteClusters FTRawBankDecoder::decode<6>( LHCb::span<const LHCb::RawBank*> ban
 }
 
 template <>
-FTLiteClusters FTRawBankDecoder::decode<4>( LHCb::span<const LHCb::RawBank*> banks, unsigned int nClusters ) const {
-  FTLiteClusters clus{nClusters};
+FTLiteClusters FTRawBankDecoder::decode<4>( const EventContext& evtCtx, LHCb::span<const LHCb::RawBank*> banks,
+                                            unsigned int nClusters ) const {
+  FTLiteClusters clus{nClusters, LHCb::getMemResource( evtCtx )};
   for ( const LHCb::RawBank* bank : banks ) { // Iterates over the banks
     LHCb::FTChannelID offset = m_readoutTool->channelIDShift( bank->sourceID() );
     auto              first  = bank->begin<short int>() + 2; // skip first 32b of the header
@@ -185,8 +187,9 @@ FTLiteClusters FTRawBankDecoder::decode<4>( LHCb::span<const LHCb::RawBank*> ban
 }
 
 template <>
-FTLiteClusters FTRawBankDecoder::decode<5>( LHCb::span<const LHCb::RawBank*> banks, unsigned int nClusters ) const {
-  FTLiteClusters clus{nClusters};
+FTLiteClusters FTRawBankDecoder::decode<5>( const EventContext& evtCtx, LHCb::span<const LHCb::RawBank*> banks,
+                                            unsigned int nClusters ) const {
+  FTLiteClusters clus{nClusters, LHCb::getMemResource( evtCtx )};
   for ( const LHCb::RawBank* bank : banks ) { // Iterates over the banks
     LHCb::FTChannelID offset  = m_readoutTool->channelIDShift( bank->sourceID() );
     auto              quarter = quarterFromChannel( offset );
@@ -244,9 +247,10 @@ FTLiteClusters FTRawBankDecoder::decode<5>( LHCb::span<const LHCb::RawBank*> ban
 }
 
 template <unsigned int vrsn>
-FTLiteClusters FTRawBankDecoder::decode( LHCb::span<const LHCb::RawBank*> banks, unsigned int nClusters ) const {
+FTLiteClusters FTRawBankDecoder::decode( const EventContext& evtCtx, LHCb::span<const LHCb::RawBank*> banks,
+                                         unsigned int nClusters ) const {
   static_assert( vrsn == 2 || vrsn == 3 );
-  FTLiteClusters clus{nClusters};
+  FTLiteClusters clus{nClusters, LHCb::getMemResource( evtCtx )};
   for ( const LHCb::RawBank* bank : banks ) {
     int      source  = bank->sourceID();
     unsigned station = source / 16 + 1u;
@@ -416,7 +420,7 @@ FTLiteClusters FTRawBankDecoder::decode( LHCb::span<const LHCb::RawBank*> banks,
 //=============================================================================
 // Main execution
 //=============================================================================
-FTLiteClusters FTRawBankDecoder::operator()( const LHCb::RawEvent& rawEvent ) const {
+FTLiteClusters FTRawBankDecoder::operator()( const EventContext& evtCtx, const LHCb::RawEvent& rawEvent ) const {
   const auto& banks = rawEvent.banks( LHCb::RawBank::FTCluster );
 
   if ( msgLevel( MSG::DEBUG ) ) debug() << "Number of raw banks " << banks.size() << endmsg;
@@ -441,15 +445,15 @@ FTLiteClusters FTRawBankDecoder::operator()( const LHCb::RawEvent& rawEvent ) co
   auto clus = [&]( unsigned int nClusters ) {
     switch ( m_decodingVersion.value() ) {
     case 2:
-      return decode<2>( banks, nClusters );
+      return decode<2>( evtCtx, banks, nClusters );
     case 3:
-      return decode<3>( banks, nClusters );
+      return decode<3>( evtCtx, banks, nClusters );
     case 4:
-      return decode<4>( banks, nClusters );
+      return decode<4>( evtCtx, banks, nClusters );
     case 5:
-      return decode<5>( banks, nClusters );
+      return decode<5>( evtCtx, banks, nClusters );
     case 6:
-      return decode<6>( banks, nClusters );
+      return decode<6>( evtCtx, banks, nClusters );
     default:
       throw GaudiException( "Unknown decoder version: " + std::to_string( vrsn ), __FILE__, StatusCode::FAILURE );
     };
diff --git a/FT/FTDAQ/src/FTRawBankDecoder.h b/FT/FTDAQ/src/FTRawBankDecoder.h
index 818ee3c18c6743eba70bf470c6a92b55b953ee94..c16528460cc6d17f7ce391c2b9d58054abbaf088 100644
--- a/FT/FTDAQ/src/FTRawBankDecoder.h
+++ b/FT/FTDAQ/src/FTRawBankDecoder.h
@@ -32,13 +32,13 @@ using FTLiteClusters = LHCb::FTLiteCluster::FTLiteClusters;
  *  @author Olivier Callot
  *  @date   2012-05-11
  */
-class FTRawBankDecoder : public Transformer<FTLiteClusters( const LHCb::RawEvent& ),
+class FTRawBankDecoder : public Transformer<FTLiteClusters( const EventContext&, const LHCb::RawEvent& ),
                                             Gaudi::Functional::Traits::BaseClass_t<FixTESPath<Gaudi::Algorithm>>> {
 public:
   /// Standard constructor
   FTRawBankDecoder( const std::string& name, ISvcLocator* pSvcLocator );
 
-  FTLiteClusters operator()( const LHCb::RawEvent& rawEvent ) const override;
+  FTLiteClusters operator()( const EventContext& evtCtx, const LHCb::RawEvent& rawEvent ) const override;
 
 private:
   PublicToolHandle<IFTReadoutTool> m_readoutTool = {this, "FTReadoutTool", "FTReadoutTool"};
@@ -57,7 +57,7 @@ private:
       "Set the decoding version"};
 
   template <unsigned int version>
-  FTLiteClusters decode( LHCb::span<const LHCb::RawBank*>, unsigned int nClusters ) const;
+  FTLiteClusters decode( const EventContext& evtCtx, LHCb::span<const LHCb::RawBank*>, unsigned int nClusters ) const;
 
   mutable Gaudi::Accumulators::MsgCounter<MSG::ERROR>   m_corrupt{this, "Possibly corrupt data. Ignoring the cluster."};
   mutable Gaudi::Accumulators::MsgCounter<MSG::WARNING> m_nonExistingModule{
diff --git a/Kernel/LHCbKernel/Kernel/MultiIndexedContainer.h b/Kernel/LHCbKernel/Kernel/MultiIndexedContainer.h
index 596273a5d85a14b94ec1692925b5f0e52789f455..1a467a1440cbe5bc50c94a4870fac885f5b23278 100644
--- a/Kernel/LHCbKernel/Kernel/MultiIndexedContainer.h
+++ b/Kernel/LHCbKernel/Kernel/MultiIndexedContainer.h
@@ -30,6 +30,8 @@ namespace ranges::views {
 #  endif
 #endif
 
+#include "EventLocalAllocator.h"
+
 #include "GaudiKernel/Range.h"
 
 namespace LHCb::Container {
@@ -124,8 +126,9 @@ namespace LHCb::Container {
     using offset_t        = unsigned short;
     using const_reference = const Hit&;
     using value_type      = Hit;
+    using allocator_type  = LHCb::Allocators::EventLocal<value_type>;
 
-    using Hits                   = typename std::vector<value_type>;
+    using Hits                   = typename std::vector<value_type, allocator_type>;
     using iterator               = typename Hits::iterator;
     using const_iterator         = typename Hits::const_iterator;
     using const_reverse_iterator = typename Hits::const_reverse_iterator;
@@ -142,16 +145,17 @@ namespace LHCb::Container {
     /**
      * Constructor for a relatively empty hit container.
      */
-    MultiIndexedContainer( size_t reserve = 0 ) {
+    MultiIndexedContainer( std::size_t reserve = 0, allocator_type alloc = {} ) : m_hits{alloc} {
       if ( reserve != 0 ) m_hits.reserve( reserve );
       clearOffsets();
       std::fill( begin( m_nIds ), end( m_nIds ), 0u );
     }
 
-    MultiIndexedContainer( std::vector<Hit>&& hits, Offsets&& offsets )
+    MultiIndexedContainer( Hits&& hits, Offsets&& offsets )
         : m_hits( std::move( hits ) ), m_offsets( std::move( offsets ) ) {}
 
-    void reserve( size_t reserve ) { m_hits.reserve( reserve ); }
+    [[nodiscard]] allocator_type get_allocator() const { return m_hits.get_allocator(); }
+    void                         reserve( size_t reserve ) { m_hits.reserve( reserve ); }
 
     template <typename... Args>
     std::pair<iterator, iterator> range_( Args&&... args ) {
@@ -315,7 +319,7 @@ namespace LHCb::Container {
     auto offsets() const { return m_offsets; }
 
   private:
-    std::vector<Hit> m_hits;
+    Hits m_hits;
 
     Offsets m_offsets;