diff --git a/algo/global/Reco.cxx b/algo/global/Reco.cxx
index a58d419693a676998a2cd0eae25f8d17dbe30b27..96063d31866e1a179eaee06f035598df5050aed9 100644
--- a/algo/global/Reco.cxx
+++ b/algo/global/Reco.cxx
@@ -270,6 +270,7 @@ RecoResults Reco::Run(const fles::Timeslice& ts)
       if (fSender != nullptr && Opts().Has(Subsystem::STS)) {
         fStsDigiQa->RegisterDigiData(&digis.fSts);
         fStsDigiQa->RegisterAuxDigiData(&auxDigis.fSts);
+        fStsDigiQa->SetTimesliceIndex(ts.index());
         fStsDigiQa->Exec();
       }
     }
diff --git a/algo/qa/Histogram.h b/algo/qa/Histogram.h
index c3179618c3853a7aa726d36a2a649e5d4413e6fa..852d9cf91bc86f3aeed64edd7ed7530aae8d3743 100644
--- a/algo/qa/Histogram.h
+++ b/algo/qa/Histogram.h
@@ -54,8 +54,8 @@ namespace cbm::algo::qa
   /// \brief Histogram control flags (bit masks)
   enum class EHistFlag : uint8_t
   {
-    StoreVsTsId    = 0b00000001,  ///< Store the histogram with the additional timeslice evolution axis 
-    OmitIntegrated = 0b00000010   ///< Omits storing integrated histogram 
+    StoreVsTsId    = 0b00000001,  ///< Store the histogram vs timeslice index
+    OmitIntegrated = 0b00000010   ///< Omits storing integrated histogram
   };
 
   /// \class  HistogramMetadata
diff --git a/algo/qa/HistogramContainer.h b/algo/qa/HistogramContainer.h
index 3816c0bc88ee80028d2bdeb67e9ff5b95ebca571..3ccdbf263ab7ee8fc81ea13ac2cdc1c23d989282 100644
--- a/algo/qa/HistogramContainer.h
+++ b/algo/qa/HistogramContainer.h
@@ -24,7 +24,7 @@ namespace cbm::algo::qa
     std::forward_list<qa::H2D> fvH2    = {};  ///< List of 2D-histograms
     std::forward_list<qa::Prof1D> fvP1 = {};  ///< List of 1D-profiles
     std::forward_list<qa::Prof2D> fvP2 = {};  ///< List of 2D-profiles
-    int fTimeSliceId                   = 0;   ///< Index of the time-slice
+    uint64_t fTimesliceId              = 0;   ///< Index of the timeslice
 
     /// \brief Resets the histograms
     void Reset();
@@ -38,7 +38,7 @@ namespace cbm::algo::qa
       ar& fvH2;
       ar& fvP1;
       ar& fvP2;
-      ar& fTimeSliceId;
+      ar& fTimesliceId;
     }
   };
 }  // namespace cbm::algo::qa
diff --git a/algo/qa/QaData.cxx b/algo/qa/QaData.cxx
index 81c53f5e8e253b2df0e700d2d6c1c56ed1f10dca..ea184f35c101a0e0ca31bc2622374e3fb9d16a96 100644
--- a/algo/qa/QaData.cxx
+++ b/algo/qa/QaData.cxx
@@ -28,10 +28,7 @@ void Data::Init(std::shared_ptr<HistogramSender> histSender)
     nHistograms += std::distance(fHistograms.fvP2.begin(), fHistograms.fvP2.end());
     vHistCfgs.reserve(nHistograms);
 
-    auto RegHist = [&](const auto& h) {
-      //vHistCfgs.emplace_back(h.GetName() + "!" + h.GetMetadataString(), fsName);
-      vHistCfgs.emplace_back(h.GetName(), fsName);
-    };
+    auto RegHist = [&](const auto& h) { vHistCfgs.emplace_back(h.GetName() + "!" + h.GetMetadataString(), fsName); };
 
     std::for_each(fHistograms.fvH1.begin(), fHistograms.fvH1.end(), RegHist);
     std::for_each(fHistograms.fvH2.begin(), fHistograms.fvH2.end(), RegHist);
diff --git a/algo/qa/QaData.h b/algo/qa/QaData.h
index 4eb94575f522557c437cf154c3662ce00e1e4123..b8347363368de0f8ba2a7fdce3ed98aeab23fd69 100644
--- a/algo/qa/QaData.h
+++ b/algo/qa/QaData.h
@@ -50,10 +50,6 @@ namespace cbm::algo::qa
     /// \param canvas  A CanvasConfig object
     void AddCanvasConfig(const CanvasConfig& canvas) { fvsCanvCfgs.push_back(canvas.ToString()); }
 
-    /// \brief Creates a QA-object and returns the pointer to it
-    template<class Obj, typename... Args>
-    Obj* MakeObj(Args... args);
-
     /// \brief Gets module name
     std::string_view GetName() const { return fsName; }
 
@@ -61,6 +57,10 @@ namespace cbm::algo::qa
     /// \param histoSender  A pointer to the histogram sender
     void Init(std::shared_ptr<HistogramSender> histoSender);
 
+    /// \brief Creates a QA-object and returns the pointer to it
+    template<class Obj, typename... Args>
+    Obj* MakeObj(Args... args);
+
     /// \brief Resets the histograms
     void Reset() { fHistograms.Reset(); }
 
@@ -69,6 +69,10 @@ namespace cbm::algo::qa
     /// \note  Calls this->Reset() after sending the message to the histogram server
     void Send(std::shared_ptr<HistogramSender> histoSender);
 
+    /// \brief Updates the timeslice index
+    /// \param timesliceId  Timeslice index
+    void SetTimesliceId(uint64_t timesliceId) { fHistograms.fTimesliceId = timesliceId; }
+
    private:
     std::string fsName;                         ///< Name of the QA module (used as a directory name)
     qa::HistogramContainer fHistograms;         ///< Histograms container
diff --git a/algo/qa/unpack/QaBase.h b/algo/qa/unpack/QaBase.h
index f63d652f2f18b0ec1cc43e9040b4219d1c7b7f2c..4e47eeb27731c15b3256714df8855d2eb3872acb 100644
--- a/algo/qa/unpack/QaBase.h
+++ b/algo/qa/unpack/QaBase.h
@@ -64,11 +64,14 @@ namespace cbm::algo::sts
       }
     }
 
+    /// \brief Register read-out setup config
+    void RegisterReadoutSetup(const ReadoutSetup& setup) { fpReadoutSetup = std::make_shared<ReadoutSetup>(setup); }
+
     /// \brief Sets usage of auxiliary data
     void SetUseAuxData(bool bAux = true) { fbAux = bAux; }
 
-    /// \brief Register read-out setup config
-    void RegisterReadoutSetup(const ReadoutSetup& setup) { fpReadoutSetup = std::make_shared<ReadoutSetup>(setup); }
+    /// \brief Sets timeslice index
+    void SetTimesliceIndex(uint64_t tsIndex) { fQaData.SetTimesliceId(tsIndex); }
 
    protected:
     qa::Data fQaData;                                        ///< QA data
diff --git a/algo/qa/unpack/StsDigiQa.cxx b/algo/qa/unpack/StsDigiQa.cxx
index 3f9a181c84b296181cfe40ccfcd9b34809fb5a23..8cb7a9ce0bd3f399233891e3c632cec1ae423889 100644
--- a/algo/qa/unpack/StsDigiQa.cxx
+++ b/algo/qa/unpack/StsDigiQa.cxx
@@ -22,6 +22,7 @@ void DigiQa::Init()
 {
   using cbm::algo::qa::CanvasConfig;
   using cbm::algo::qa::Data;
+  using cbm::algo::qa::EHistFlag;
   using cbm::algo::qa::H1D;
   using cbm::algo::qa::H2D;
   using cbm::algo::qa::PadConfig;
@@ -69,6 +70,9 @@ void DigiQa::Init()
         auto name              = format("sts_digi_{}_channel", aName);
         auto titl              = format("Number of digis per channel for module {};channel;N_{{digis}}", aTitl);
         fvphAddressChannel[iM] = fQaData.MakeObj<H1D>(name, titl, 2048, -0.5, 2047.5);
+        if (fbAux) {
+          fvphAddressChannel[iM]->SetFlag(EHistFlag::StoreVsTsId);
+        }
         pad.RegisterHistogram(fvphAddressChannel[iM], "hist");
         canv.AddPadConfig(pad);
       }
diff --git a/core/qa/CbmQaOnlineInterface.cxx b/core/qa/CbmQaOnlineInterface.cxx
index 0b5823b10a0326365cefa128ecd0d7cef69b5d0e..2554020e60290b5c6c5c6784f61a4e73534ea458 100644
--- a/core/qa/CbmQaOnlineInterface.cxx
+++ b/core/qa/CbmQaOnlineInterface.cxx
@@ -22,25 +22,40 @@ using cbm::algo::qa::Prof2D;
 using cbm::qa::OnlineInterface;
 using cbm::qa::RootHistogramAccessor;
 
+// ---------------------------------------------------------------------------------------------------------------------
+//
+void OnlineInterface::AddSlice(const H1D& src, double value, TH2D* dst)
+{
+  auto* pDst = static_cast<RootHistogramAccessor<TH2D>*>(dst);
+  pDst->AddSliceFromQaHistogram<H1D>(src, value);
+}
+
+// ---------------------------------------------------------------------------------------------------------------------
+//
+void OnlineInterface::AddSlice(const Prof1D& src, double value, TProfile2D* dst)
+{
+  auto* pDst = static_cast<RootHistogramAccessor<TProfile2D>*>(dst);
+  pDst->AddSliceFromQaHistogram<Prof1D>(src, value);
+}
 
 // ---------------------------------------------------------------------------------------------------------------------
 //
-TH1D* OnlineInterface::ROOTHistogram(const cbm::algo::qa::H1D& hist)
+TH1D* OnlineInterface::ROOTHistogram(const H1D& hist)
 {
   int nBins   = hist.GetNbinsX();
   double xMin = hist.GetMinX();
   double xMax = hist.GetMaxX();
   bool add    = TH1::AddDirectoryStatus();
   TH1::AddDirectory(false);
-  auto* pRes = new RootHistogramAccessor<TH1D, H1D>(hist.GetName().c_str(), hist.GetTitle().c_str(), nBins, xMin, xMax);
+  auto* pRes = new RootHistogramAccessor<TH1D>(hist.GetName().c_str(), hist.GetTitle().c_str(), nBins, xMin, xMax);
   TH1::AddDirectory(add);
-  pRes->SetFromQaHistogram(hist);
+  pRes->SetFromQaHistogram<H1D>(hist);
   return pRes;
 }
 
 // ---------------------------------------------------------------------------------------------------------------------
 //
-TH2D* OnlineInterface::ROOTHistogram(const cbm::algo::qa::H2D& hist)
+TH2D* OnlineInterface::ROOTHistogram(const H2D& hist)
 {
   int nBinsX  = hist.GetNbinsX();
   double xMin = hist.GetMinX();
@@ -50,10 +65,10 @@ TH2D* OnlineInterface::ROOTHistogram(const cbm::algo::qa::H2D& hist)
   double yMax = hist.GetMaxY();
   bool add    = TH1::AddDirectoryStatus();
   TH1::AddDirectory(false);
-  auto* pRes = new RootHistogramAccessor<TH2D, H2D>(hist.GetName().c_str(), hist.GetTitle().c_str(), nBinsX, xMin, xMax,
-                                                    nBinsY, yMin, yMax);
+  auto* pRes = new RootHistogramAccessor<TH2D>(hist.GetName().c_str(), hist.GetTitle().c_str(), nBinsX, xMin, xMax,
+                                               nBinsY, yMin, yMax);
   TH1::AddDirectory(add);
-  pRes->SetFromQaHistogram(hist);
+  pRes->SetFromQaHistogram<H2D>(hist);
   return pRes;
 }
 
@@ -70,9 +85,9 @@ TProfile* OnlineInterface::ROOTHistogram(const Prof1D& prof)
   double yMax      = prof.GetMaxY();
   bool add         = TH1::AddDirectoryStatus();
   TH1::AddDirectory(false);
-  auto* pRes = new RootHistogramAccessor<TProfile, Prof1D>(name, titl, nBinsX, xMin, xMax, yMin, yMax);
+  auto* pRes = new RootHistogramAccessor<TProfile>(name, titl, nBinsX, xMin, xMax, yMin, yMax);
   TH1::AddDirectory(add);
-  pRes->SetFromQaHistogram(prof);
+  pRes->SetFromQaHistogram<Prof1D>(prof);
   return pRes;
 }
 
@@ -92,9 +107,8 @@ TProfile2D* OnlineInterface::ROOTHistogram(const Prof2D& prof)
   double zMax      = prof.GetMaxZ();
   bool add         = TH1::AddDirectoryStatus();
   TH1::AddDirectory(false);
-  auto* pRes =
-    new RootHistogramAccessor<TProfile2D, Prof2D>(name, titl, nBinsX, xMin, xMax, nBinsY, yMin, yMax, zMin, zMax);
+  auto* pRes = new RootHistogramAccessor<TProfile2D>(name, titl, nBinsX, xMin, xMax, nBinsY, yMin, yMax, zMin, zMax);
   TH1::AddDirectory(add);
-  pRes->SetFromQaHistogram(prof);
+  pRes->SetFromQaHistogram<Prof2D>(prof);
   return pRes;
 }
diff --git a/core/qa/CbmQaOnlineInterface.h b/core/qa/CbmQaOnlineInterface.h
index 462c90fb20d6e997394014e3424f14e625947ae1..64a48f8440a4ca48e09f5fa09c67de417952e047 100644
--- a/core/qa/CbmQaOnlineInterface.h
+++ b/core/qa/CbmQaOnlineInterface.h
@@ -21,6 +21,13 @@
 #include <log.hpp>
 #include <type_traits>
 
+namespace
+{
+  using cbm::algo::qa::H1D;
+  using cbm::algo::qa::H2D;
+  using cbm::algo::qa::Prof1D;
+  using cbm::algo::qa::Prof2D;
+}  // namespace
 
 namespace cbm::qa
 {
@@ -30,7 +37,7 @@ namespace cbm::qa
   /// The ROOT TProfile classes do not alow to set a profile from outside, so we need to set all the
   /// fields directly. Also the access to TH1/TH2 protected fields is needed in order to set the
   /// total sums of w*x, w*x*x, w*y, w*x*y, and w*y*y.
-  template<class RootHistogram, class QaHistogram>
+  template<class RootHistogram>
   class RootHistogramAccessor : public RootHistogram {
 
    public:
@@ -39,7 +46,16 @@ namespace cbm::qa
     {
     }
 
+    /// \brief Sets slice from the lower-dimension histogram
+    /// \tparam Source histogram type
+    /// \param src  Source histogram
+    /// \param val  Target value on the additional axis
+    template<class SourceQaHistogram>
+    void AddSliceFromQaHistogram(const SourceQaHistogram& histo, double val);
+
     /// \brief Sets fields from qa histogram
+    /// \param histo  Source histogram
+    template<class QaHistogram>
     void SetFromQaHistogram(const QaHistogram& histo);
   };
 
@@ -47,25 +63,38 @@ namespace cbm::qa
   /// \brief  A collection of tools for online QA object conversions
   class OnlineInterface {
    public:
+    // TODO: generalize
+    /// \brief Fills a slice of a histogram of a higher dimension for a given value (....)
+    /// \param src   1D source histogram
+    /// \param value Slice coordinate
+    /// \param dst   Destination 2D-histogram
+    static void AddSlice(const H1D& src, double value, TH2D* dst);
+
+    /// \brief Fills a slice of a profile of a higher dimension for a given value (....)
+    /// \param src   1D source profile
+    /// \param value Slice coordinate
+    /// \param dst   Destination 2D-profile
+    static void AddSlice(const Prof1D& src, double value, TProfile2D* dst);
+
     /// \brief Converts histogram H1D to ROOT histogram TH1D
     /// \param hist  1D-histogram
     /// \note  Allocates memory on heap for the ROOT histogram
-    static TH1D* ROOTHistogram(const cbm::algo::qa::H1D& hist);
+    static TH1D* ROOTHistogram(const H1D& hist);
 
     /// \brief Converts histogram H2D to ROOT histogram TH2D
     /// \param hist  1D-histogram
     /// \note  Allocates memory on heap for the ROOT histogram
-    static TH2D* ROOTHistogram(const cbm::algo::qa::H2D& hist);
+    static TH2D* ROOTHistogram(const H2D& hist);
 
     /// \brief Converts profile Prof1D to ROOT TProfile
     /// \param prof  1D-profile
     /// \note  Allocates memory on heap for the ROOT histogram
-    static TProfile* ROOTHistogram(const cbm::algo::qa::Prof1D& prof);
+    static TProfile* ROOTHistogram(const Prof1D& prof);
 
     /// \brief Converts profile Prof2D to ROOT TProfile2D
     /// \param prof  2D-profile
     /// \note  Allocates memory on heap for the ROOT histogram
-    static TProfile2D* ROOTHistogram(const cbm::algo::qa::Prof2D& prof);
+    static TProfile2D* ROOTHistogram(const Prof2D& prof);
   };
 }  // namespace cbm::qa
 
@@ -74,8 +103,49 @@ namespace cbm::qa
 {
   // -------------------------------------------------------------------------------------------------------------------
   //
-  template<class RootHistogram, class QaHistogram>
-  void RootHistogramAccessor<RootHistogram, QaHistogram>::SetFromQaHistogram(const QaHistogram& hist)
+  template<class RootHistogram>
+  template<class QaHistogram>
+  void RootHistogramAccessor<RootHistogram>::AddSliceFromQaHistogram(const QaHistogram& src, double val)
+  {
+    constexpr bool IsDstH2D    = std::is_same_v<RootHistogram, TH2D>;
+    constexpr bool IsDstProf2D = std::is_same_v<RootHistogram, TProfile2D>;
+    constexpr bool IsSrcH1D    = std::is_same_v<QaHistogram, H1D>;
+    constexpr bool IsSrcProf1D = std::is_same_v<QaHistogram, Prof1D>;
+
+    static_assert((IsDstH2D && IsSrcH1D) || (IsDstProf2D && IsSrcProf1D),
+                  "function not implemented for a given (RootHistogram, QaHistogram) pair");
+
+    auto iBinX = this->GetXaxis()->FindBin(val);
+    for (int iBinY = 0; iBinY <= this->GetNbinsY() + 1; ++iBinY) {
+      int iGlobBin = this->GetBin(iBinX, iBinY);
+      auto binSrc  = src.GetBinAccumulator(iBinY);
+      if constexpr (IsSrcH1D) {
+        this->fArray[iGlobBin] += binSrc.value();
+        if (this->fSumw2.fN) {
+          this->fSumw2.fArray[iGlobBin] += binSrc.variance();
+        }
+      }
+      else if constexpr (IsSrcProf1D) {
+        this->fArray[iGlobBin] += binSrc.GetSumWV();
+        this->fBinEntries.fArray[iGlobBin] += binSrc.GetSumW();
+        this->fSumw2.fArray[iGlobBin] += binSrc.GetSumWV2();
+        this->fBinSumw2.fArray[iGlobBin] += binSrc.GetSumW2();
+        this->fTsumwz += binSrc.GetSumWV();
+        this->fTsumwz2 += binSrc.GetSumWV2();
+      }
+    }
+    this->fTsumw += src.GetTotSumW();
+    this->fTsumw2 += src.GetTotSumW2();
+    this->fTsumwx += src.GetTotSumWX();
+    this->fTsumwx2 += src.GetTotSumWX2();
+    this->SetEntries(this->GetEntries() + src.GetEntries());
+  }
+
+  // -------------------------------------------------------------------------------------------------------------------
+  //
+  template<class RootHistogram>
+  template<class QaHistogram>
+  void RootHistogramAccessor<RootHistogram>::SetFromQaHistogram(const QaHistogram& hist)
   {
     // Set individual bin properties
     if constexpr (std::is_same_v<RootHistogram, TProfile> || std::is_same_v<RootHistogram, TProfile2D>) {
diff --git a/services/histserv/app/Application.cxx b/services/histserv/app/Application.cxx
index bb763da0e7e68463e93a2b8ab0f46c990a57bbfb..2e698f8b9b8219e45298092d8362cd2611216698 100644
--- a/services/histserv/app/Application.cxx
+++ b/services/histserv/app/Application.cxx
@@ -44,6 +44,11 @@ namespace b_ar = boost::archive;
 
 using cbm::services::histserv::Application;
 
+using cbm::algo::qa::H1D;
+using cbm::algo::qa::H2D;
+using cbm::algo::qa::Prof1D;
+using cbm::algo::qa::Prof2D;
+
 // ---------------------------------------------------------------------------------------------------------------------
 //
 Application::Application(ProgramOptions const& opt, volatile sig_atomic_t* signalStatus)
@@ -167,6 +172,31 @@ void Application::UpdateHttpServer()
   }
 }
 
+// ---------------------------------------------------------------------------------------------------------------------
+//
+//template<class HistoSrc>
+//bool Appliaction::CollectHistograms(const std::forward_list<HistoSrc>& container)
+//{
+//  for (const auto& hist : container) {
+//    if (!hist.GetFlag(cbm::algo::qa::EHistFlag::OmitIntegrated)) {
+//      if (!ReadHistogram<TH1>(hist)) {
+//        return false;
+//      }
+//    }
+//    if (hist.GetFlag(cbm::algo::qa::EHistFlag::StoreVsTsId)) {
+//      if constexpr (std::is_same_v<HistSrc, H1D> || std::is_same_v<HistSrc, Prof1D>) {
+//        if (!ReadHistogramExtendedTsId(hist, timesliceId)) {
+//          return false;
+//        }
+//      }
+//      else {
+//        LOG(warn) << "Histogram " << rHist.GetName() << " cannot be plotted vs. TS index. Ignoring";
+//      }
+//    }
+//  }
+//  return true;
+//}
+
 // ---------------------------------------------------------------------------------------------------------------------
 //
 bool Application::ReceiveData(zmq::message_t& msg)
@@ -201,24 +231,45 @@ bool Application::ReceiveData(zmq::message_t& msg)
   /// FIXME: Should be placed in a tools/interface/whatever library with all similar functions!!
   /// FIXME: Reverse OP need to be implemented + CI unit tests for back and forth in each direction (ROOT <-> Algo)
   /// FIXME: Lead to "Warning in <TROOT::Append>: Replacing existing TH1: xxxxxx (Potential memory leak)."
+  auto timesliceId = vHist.fTimesliceId;
 
-  // Collect histograms
-  auto CollectHistogram = [&](const auto& container) -> bool {
-    for (auto& source : container) {
-      TH1* hist = cbm::qa::OnlineInterface::ROOTHistogram(source);
-      if (!ReadHistogram<TH1>(hist)) {
-        delete hist;
-        return false;
+  // Collects 1D-histograms (with possible extention vs. TS)
+  auto CollectHistogram1D = [&](const auto& container) -> bool {
+    for (const auto& hist : container) {
+      if (!hist.GetFlag(cbm::algo::qa::EHistFlag::OmitIntegrated)) {
+        if (!ReadHistogram<TH1>(hist)) {
+          return false;
+        }
+      }
+      if (hist.GetFlag(cbm::algo::qa::EHistFlag::StoreVsTsId)) {
+        if (!ReadHistogramExtendedTsId(hist, timesliceId)) {
+          return false;
+        }
+      }
+    }
+    return true;
+  };
+
+  // Collects 2D-histograms
+  // TODO: Add a possibility to store multiple histograms vs each time-slice depending on the StoreVsTsId flag
+  // NOTE: TProfile2D can be extended to TProfile3D, and TH2D can be extended to TH3D. Should we provide such a possibility,
+  //       or it does not make sence? (SZh)
+  auto CollectHistogram2D = [&](const auto& container) -> bool {
+    for (const auto& hist : container) {
+      if (!hist.GetFlag(cbm::algo::qa::EHistFlag::OmitIntegrated)) {
+        if (!ReadHistogram<TH1>(hist)) {
+          return false;
+        }
       }
-      delete hist;
     }
     return true;
   };
 
-  if (!CollectHistogram(vHist.fvH1)) return false;
-  if (!CollectHistogram(vHist.fvH2)) return false;
-  if (!CollectHistogram(vHist.fvP1)) return false;
-  if (!CollectHistogram(vHist.fvP2)) return false;
+  if (!CollectHistogram1D(vHist.fvH1)) return false;
+  if (!CollectHistogram2D(vHist.fvH2)) return false;
+  if (!CollectHistogram1D(vHist.fvP1)) return false;
+  if (!CollectHistogram2D(vHist.fvP2)) return false;
+
 
   /// If new histos received, try to prepare as many canvases as possible
   /// Should be expensive on start and cheap afterward
@@ -333,12 +384,10 @@ bool Application::ReceiveHistoConfig(zmq::message_t& msg)
   }
 
   // Parse metadata
-  LOG(info) << "\n\n\n!!!!!! tempObect-1: " << tempObject.first << ", " << tempObject.second << "\n\n";
   std::string& name = tempObject.first;
   std::string metadataMsg{};
   std::tie(name, metadataMsg) = HistogramMetadata::SeparateNameAndMetadata(name);
-  LOG(info) << "\n\n\n!!!!!! tempObect-2: " << tempObject.first << ", " << tempObject.second << "\n\n";
-  auto metadata = HistogramMetadata(metadataMsg);
+  auto metadata               = HistogramMetadata(metadataMsg);
 
   if (!metadata.GetFlag(EHistFlag::OmitIntegrated)) {
     // Main (integrated over time) histogram
@@ -497,13 +546,14 @@ bool Application::ReceiveConfigAndData(std::vector<zmq::message_t>& vMsg)
 
 // ---------------------------------------------------------------------------------------------------------------------
 //
-template<class HistoT>
-bool Application::ReadHistogram(HistoT* pHist)
+template<class HistoDst, class HistoSrc>
+bool Application::ReadHistogram(const HistoSrc& rHist)
 {
+  HistoDst* pHist = cbm::qa::OnlineInterface::ROOTHistogram(rHist);
   int index1 = FindHistogram(pHist->GetName());
   if (-1 == index1) {
     // ----- Creating new histogram
-    HistoT* histogram_new = static_cast<HistoT*>(pHist->Clone());
+    HistoDst* histogram_new = static_cast<HistoDst*>(pHist->Clone());
     fArrayHisto.Add(histogram_new);
 
     LOG(info) << "Received new histo " << pHist->GetName();
@@ -543,15 +593,110 @@ bool Application::ReadHistogram(HistoT* pHist)
   else {
     // ----- Update histogram
     LOG(debug) << "Received update for: " << pHist->GetName();
-    HistoT* histogram_existing = dynamic_cast<HistoT*>(fArrayHisto.At(index1));
+    HistoDst* histogram_existing = dynamic_cast<HistoDst*>(fArrayHisto.At(index1));
     if (nullptr == histogram_existing) {
       LOG(error) << "CbmMqHistoServer::ReadHistogram => "
                  << "Incompatible type found during update for histo " << pHist->GetName();
+      delete pHist;
       return false;
     }  // if( nullptr == histogram_existing )
 
     histogram_existing->Add(pHist);
   }  // else of if (-1 == index1)
+  delete pHist;
+  return true;
+}
+
+// ---------------------------------------------------------------------------------------------------------------------
+//
+template<class HistoSrc>
+bool Application::ReadHistogramExtendedTsId(const HistoSrc& rHist, uint64_t tsIndex)
+{
+  constexpr bool IsSrcH1D    = std::is_same_v<HistoSrc, H1D>;
+  constexpr bool IsSrcProf1D = std::is_same_v<HistoSrc, Prof1D>;
+
+  if constexpr (IsSrcH1D || IsSrcProf1D) {
+    /* clang-format off */
+    using HistoDst_t = typename std::conditional<IsSrcH1D, TH2D, TProfile2D>::type;
+    /* clang-format on */
+
+    std::string sHistoName = rHist.GetName() + std::string(ksTsIdSuffix);
+    int index1             = FindHistogram(sHistoName.c_str());
+    if (-1 == index1) {
+      // ----- Creating new histogram
+      HistoDst_t* histogram_new = nullptr;
+      {
+        std::string title = rHist.GetTitle();
+        title.insert(title.find_first_of(';'), " vs. TS index;TS index");
+        int nBinsX  = fConfig.fNofTsToStore;
+        double minX = static_cast<double>(tsIndex) - 0.5;
+        double maxX = static_cast<double>(tsIndex + nBinsX) - 0.5;
+        int nBinsY  = rHist.GetNbinsX();
+        double minY = rHist.GetMinX();
+        double maxY = rHist.GetMaxX();
+        if constexpr (IsSrcH1D) {
+          histogram_new = new TH2D(sHistoName.c_str(), title.c_str(), nBinsX, minX, maxX, nBinsY, minY, maxY);
+        }
+        else if constexpr (IsSrcProf1D) {
+          double minZ = rHist.GetMinY();
+          double maxZ = rHist.GetMaxY();
+          histogram_new =
+            new TProfile2D(sHistoName.c_str(), title.c_str(), nBinsX, minX, maxX, nBinsY, minY, maxY, minZ, maxZ);
+        }
+      }
+      cbm::qa::OnlineInterface::AddSlice(rHist, double(tsIndex), histogram_new);
+      fArrayHisto.Add(histogram_new);
+
+      LOG(info) << "Received new histo " << sHistoName;
+
+      /// If new histo received, try to register it if configuration available
+      if (!fbAllHistosRegistered) {
+        for (uint32_t uHist = 0; uHist < fvpsHistosFolder.size(); ++uHist) {
+          /// Jump histos already ready
+          if (fvbHistoRegistered[uHist]) {  //
+            continue;
+          }
+
+          /// Check if name matches one in config for others
+          if (fvpsHistosFolder[uHist].first == histogram_new->GetName()) {
+            fvHistos[uHist] = std::pair<TNamed*, std::string>(histogram_new, fvpsHistosFolder[uHist].second);
+            fServer->Register(Form("/%s", fvHistos[uHist].second.data()), fvHistos[uHist].first);
+            fvbHistoRegistered[uHist] = true;
+
+            LOG(info) << "registered histo " << fvHistos[uHist].first->GetName() << " in folder "
+                      << fvHistos[uHist].second;
+
+
+            /// Update flag telling whether all known histos are registered
+            fbAllHistosRegistered = true;
+            for (uint32_t uIdx = 0; uIdx < fvbHistoRegistered.size(); ++uIdx) {
+              if (!fvbHistoRegistered[uIdx]) {
+                fbAllHistosRegistered = false;
+                break;
+              }  // if( !fvbHistoRegistered[ uIdx ] )
+            }    // for( uint32_t uIdx = 0; uIdx < fvbHistoRegistered.size(); ++uIdx )
+
+            break;
+          }  // if( fvpsHistosFolder[ uHist ].first == histogram_new->GetName() )
+        }    // for( uint32_t uCanv = 0; uCanv < fvpsCanvasConfig.size(); ++uCanv )
+      }      // if( !fbAllCanvasReady )
+    }        // if (-1 == index1)
+    else {
+      // ----- Update histogram
+      LOG(debug) << "Received update for: " << sHistoName;
+      HistoDst_t* histogram_existing = dynamic_cast<HistoDst_t*>(fArrayHisto.At(index1));
+      if (nullptr == histogram_existing) {
+        LOG(error) << "CbmMqHistoServer::ReadHistogram => "
+                   << "Incompatible type found during update for histo " << sHistoName;
+        return false;
+      }  // if( nullptr == histogram_existing )
+      cbm::qa::OnlineInterface::AddSlice(rHist, double(tsIndex), histogram_existing);
+    }  // else of if (-1 == index1)
+  }
+  else {
+    LOG(warn) << "Histogram " << rHist.GetName() << " cannot be plotted vs. TS index. Ignoring";
+  }
+
   return true;
 }
 
diff --git a/services/histserv/app/Application.h b/services/histserv/app/Application.h
index 7d7d55d22ea5814b232b80c0f4264e026d06f1a7..53cbdc848397df4a36582cd393e288fc07f09253 100644
--- a/services/histserv/app/Application.h
+++ b/services/histserv/app/Application.h
@@ -12,6 +12,7 @@
 #include "ui_callbacks.h"
 
 #include <csignal>
+#include <forward_list>
 #include <memory>
 #include <string>
 #include <string_view>
@@ -23,6 +24,12 @@ class TNamed;
 
 namespace cbm::services::histserv
 {
+  /// \struct AppConfig
+  /// \brief  Application configuarion
+  struct AppConfig {
+    int fNofTsToStore = 400;  ///< Number of consequent timeslices to store
+  };
+
   class Application {
     static constexpr std::string_view ksTsIdSuffix = "_ts_id";  ///< Suffix of additional histograms vs. TS index
 
@@ -46,6 +53,12 @@ namespace cbm::services::histserv
     void UpdateHttpServer();
 
    private:
+    /// \brief  Collects histograms of the same type from the histogram list
+    /// \tparam HistoSrc  Histogram type
+    /// \param  container  List of histograms
+    //template<class HistoSrc>
+    //bool CollectHistograms(const std::forward_list<HistoSrc>& container);
+
     //const std::string& ConfigFile() const;
     /// \param name  A name of the histogram
     int FindHistogram(const std::string& name);
@@ -54,10 +67,18 @@ namespace cbm::services::histserv
     bool ResetHistograms();
 
     /// \brief  Read a histogram
-    /// \tparam HistoT  Histogram type
-    /// \param  pHist   Pointer to the histogram
-    template<class HistoT>
-    bool ReadHistogram(HistoT* pHist);
+    /// \tparam HistoDst  Destination histogram type
+    /// \tparam HistoSrc  Source histogram type
+    /// \param  rHist  Reference to the source histogram
+    template<class HistoDst, class HistoSrc>
+    bool ReadHistogram(const HistoSrc& rHist);
+
+    /// \brief  Reads a histogram slice for an extended histogram with the TS ID
+    /// \tparam HistoSrc  Source histogram type
+    /// \param  rHistSrc  Reference to the source histogram
+    /// \param  tsIndex   Index of timeslice
+    template<class HistoSrc>
+    bool ReadHistogramExtendedTsId(const HistoSrc& pHistSrc, uint64_t tsIndex);
 
     /// \brief Find histogram index in the histogram array
     /// \brief Receives histograms
@@ -117,6 +138,7 @@ namespace cbm::services::histserv
     std::vector<std::pair<std::string, std::string>> fvpsCanvasConfig = {};
     std::vector<bool> fvbCanvasReady                                  = {};
     bool fbAllCanvasReady                                             = false;
+    AppConfig fConfig;
 
     std::vector<std::pair<TNamed*, std::string>> fvHistos  = {};  ///< Vector of Histos pointers and folder path
     std::vector<bool> fvbHistoRegistered                   = {};