diff --git a/algo/qa/QaData.cxx b/algo/qa/QaData.cxx
index 235bb3ddbf520a14a154e4e0e7aea14f54641cb0..5abee21fe5cc2520d4dccf44b61addc2bb0e0d9a 100644
--- a/algo/qa/QaData.cxx
+++ b/algo/qa/QaData.cxx
@@ -19,17 +19,31 @@ using cbm::algo::qa::Data;
 void Data::Init(std::shared_ptr<HistogramSender> histSender)
 try {
   if (histSender.get()) {
+    // Check, if the tasks list was initialized properly: at least one task must be initialized
+    if (fvTaskProperties.empty()) {
+      std::stringstream msg;
+      msg << "a qa::Data instance was not initialized properly: no task was registered. The list of the histograms:\n";
+      auto ShowName = [&](const auto& h) { msg << " - " << h.GetName() << '\n'; };
+      std::for_each(fHistograms.fvH1.begin(), fHistograms.fvH1.end(), ShowName);
+      std::for_each(fHistograms.fvH2.begin(), fHistograms.fvH2.end(), ShowName);
+      std::for_each(fHistograms.fvP1.begin(), fHistograms.fvP1.end(), ShowName);
+      std::for_each(fHistograms.fvP2.begin(), fHistograms.fvP2.end(), ShowName);
+      msg << "Please, insure that you either instantiate the qa::Data with the Data(std::string_view name) constructor";
+      msg << ", or provide a task name explicitly with the function Data::RegisterNewTask(std::string_view name)";
+      throw std::runtime_error(msg.str());
+    }
+
     // Forming a histogram config message
     std::vector<std::pair<std::string, std::string>> vHistCfgs;
     size_t nHistograms = 0;
     // NOTE: Important to keep the order of filling the histograms: 1D -> 2D -> ..
-    nHistograms += std::distance(fHistograms.fvH1.begin(), fHistograms.fvH1.end());
-    nHistograms += std::distance(fHistograms.fvH2.begin(), fHistograms.fvH2.end());
-    nHistograms += std::distance(fHistograms.fvP1.begin(), fHistograms.fvP1.end());
-    nHistograms += std::distance(fHistograms.fvP2.begin(), fHistograms.fvP2.end());
+    nHistograms += fNofH1;
+    nHistograms += fNofH2;
+    nHistograms += fNofP1;
+    nHistograms += fNofP2;
     vHistCfgs.reserve(nHistograms);
 
-    for (const auto& task: fvTaskProperties) {
+    for (const auto& task : fvTaskProperties) {
       auto RegHist = [&](const auto& h) {
         if (!h.GetMetadata().CheckFlags()) {
           std::stringstream msg;
@@ -78,13 +92,11 @@ void Data::RegisterNewTask(std::string_view name)
   auto itH2 = fHistograms.fvH2.begin();
   auto itP1 = fHistograms.fvP1.begin();
   auto itP2 = fHistograms.fvP2.begin();
-  fvTaskProperties.emplace_back(TaskProperties{
-    .fsName   = {name.begin(), name.end()},
-    .fRangeH1 = std::make_pair(itH1, itH1),
-    .fRangeH2 = std::make_pair(itH2, itH2),
-    .fRangeP1 = std::make_pair(itP1, itP1),
-    .fRangeP2 = std::make_pair(itP2, itP2)
-  });
+  fvTaskProperties.emplace_back(TaskProperties{.fsName   = {name.begin(), name.end()},
+                                               .fRangeH1 = std::make_pair(itH1, itH1),
+                                               .fRangeH2 = std::make_pair(itH2, itH2),
+                                               .fRangeP1 = std::make_pair(itP1, itP1),
+                                               .fRangeP2 = std::make_pair(itP2, itP2)});
 }
 
 // ---------------------------------------------------------------------------------------------------------------------
@@ -92,11 +104,7 @@ void Data::RegisterNewTask(std::string_view name)
 void Data::Send(std::shared_ptr<HistogramSender> histoSender)
 {
   histoSender->PrepareAndSendMsg(fHistograms, zmq::send_flags::none);
-  auto nH1 = std::distance(fHistograms.fvH1.begin(), fHistograms.fvH1.end());
-  auto nH2 = std::distance(fHistograms.fvH2.begin(), fHistograms.fvH2.end());
-  auto nP1 = std::distance(fHistograms.fvP1.begin(), fHistograms.fvP1.end());
-  auto nP2 = std::distance(fHistograms.fvP2.begin(), fHistograms.fvP2.end());
-  L_(info) << fsTaskNames << ": Published " << nH1 << " 1D- and " << nH2 << " 2D-histograms, " << nP1 << " 1D- and " << nP2
-           << " 2D-profiles";
+  L_(info) << fsTaskNames << ": Published " << fNofH1 << " 1D- and " << fNofH2 << " 2D-histograms, " << fNofP1
+           << " 1D- and " << fNofP2 << " 2D-profiles";
   this->Reset();
 }
diff --git a/algo/qa/QaData.h b/algo/qa/QaData.h
index fcb1afced29bce62d00a9136c1e769d2f808ff23..9c4747440156fe524fd87268b292b512b371e951 100644
--- a/algo/qa/QaData.h
+++ b/algo/qa/QaData.h
@@ -10,10 +10,10 @@
 #pragma once
 
 #include "AlgoFairloggerCompat.h"
+#include "base/HistogramSender.h"
 #include "qa/CanvasConfig.h"
 #include "qa/HistogramContainer.h"
 #include "qa/TaskProperties.h"
-#include "base/HistogramSender.h"
 
 #include <boost/serialization/forward_list.hpp>
 
@@ -79,10 +79,15 @@ namespace cbm::algo::qa
     void RegisterNewTask(std::string_view name);
 
    private:
-    qa::HistogramContainer fHistograms;                ///< Histograms container
+    qa::HistogramContainer fHistograms;                ///< A container of histograms, which forms a zmq message
     std::string fsTaskNames;                           ///< A string containing names of tasks
     std::vector<qa::TaskProperties> fvTaskProperties;  ///< A vector to store properties for multiple QA-tasks
     std::vector<std::string> fvsCanvCfgs = {};         ///< Vector of canvas configs
+
+    uint32_t fNofH1{0};  ///< Number of 1D-histograms
+    uint32_t fNofH2{0};  ///< Number of 2D-histograms
+    uint32_t fNofP1{0};  ///< Number of 1D-profiles
+    uint32_t fNofP2{0};  ///< Number of 2D-profiles
   };
 
   // -------------------------------------------------------------------------------------------------------------------
@@ -92,21 +97,25 @@ namespace cbm::algo::qa
   {
     if constexpr (std::is_same_v<Obj, cbm::algo::qa::H1D>) {
       Obj* res = &(fHistograms.fvH1.emplace_front(args...));
+      ++fNofH1;
       fvTaskProperties.back().fRangeH1.first = fHistograms.fvH1.begin();
       return res;
     }
     else if constexpr (std::is_same_v<Obj, cbm::algo::qa::H2D>) {
       Obj* res = &(fHistograms.fvH2.emplace_front(args...));
+      ++fNofH2;
       fvTaskProperties.back().fRangeH2.first = fHistograms.fvH2.begin();
       return res;
     }
     else if constexpr (std::is_same_v<Obj, cbm::algo::qa::Prof1D>) {
       Obj* res = &(fHistograms.fvP1.emplace_front(args...));
+      ++fNofP1;
       fvTaskProperties.back().fRangeP1.first = fHistograms.fvP1.begin();
       return res;
     }
     else if constexpr (std::is_same_v<Obj, cbm::algo::qa::Prof2D>) {
       Obj* res = &(fHistograms.fvP2.emplace_front(args...));
+      ++fNofP2;
       fvTaskProperties.back().fRangeP2.first = fHistograms.fvP2.begin();
       return res;
     }
diff --git a/algo/qa/QaManager.cxx b/algo/qa/QaManager.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..dc831fa2ecc0f92f4c58a3c05df5c74a785908ef
--- /dev/null
+++ b/algo/qa/QaManager.cxx
@@ -0,0 +1,26 @@
+/* Copyright (C) 2025 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
+   SPDX-License-Identifier: GPL-3.0-only
+   Authors: Sergei Zharko [committer] */
+
+/// \file   QaManager.cxx
+/// \date   09.02.2025
+/// \brief  QA manager for the online data reconstruction
+/// \author Sergei Zharko <s.zharko@gsi.de>
+
+#include "qa/QaManager.h"
+
+using cbm::algo::HistogramSender;
+using cbm::algo::qa::Data;
+using cbm::algo::qa::Manager;
+
+// ---------------------------------------------------------------------------------------------------------------------
+//
+Manager::Manager(std::shared_ptr<HistogramSender> histoSender) : fpSender(histoSender) {}
+
+// ---------------------------------------------------------------------------------------------------------------------
+//
+void Manager::Init() { fpData->Init(fpSender); }
+
+// ---------------------------------------------------------------------------------------------------------------------
+//
+void Manager::SendHistograms() { fpData->Send(fpSender); }
diff --git a/algo/qa/QaManager.h b/algo/qa/QaManager.h
new file mode 100644
index 0000000000000000000000000000000000000000..4a291800c53d2681905e1bd7ba4179e0a784cc63
--- /dev/null
+++ b/algo/qa/QaManager.h
@@ -0,0 +1,59 @@
+/* Copyright (C) 2025 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
+   SPDX-License-Identifier: GPL-3.0-only
+   Authors: Sergei Zharko [committer] */
+
+/// \file   QaManager.h
+/// \date   09.02.2025
+/// \brief  QA manager for the online data reconstruction
+/// \author Sergei Zharko <s.zharko@gsi.de>
+
+#pragma once
+
+#include "base/HistogramSender.h"
+#include "base/SubChain.h"
+#include "qa/QaData.h"
+
+namespace cbm::algo::qa
+{
+  /// \class Manager
+  /// \brief A central class to manage the histogram storage and sending to the histogram server
+  class Manager : public SubChain {
+   public:
+    /// \brief Constructor
+    /// \param histoSender  A histogram sender instance
+    Manager(std::shared_ptr<HistogramSender> histoSender = nullptr);
+
+    /// \brief Copy constructor
+    Manager(const Manager&) = delete;
+
+    /// \brief Move constructor
+    Manager(Manager&&) = delete;
+
+    /// \brief Destructor
+    ~Manager() = delete;
+
+    /// \brief Copy assignment operator
+    Manager& operator=(const Manager&) = delete;
+
+    /// \brief Move assignment operator
+    Manager& operator=(Manager&&) = delete;
+
+    /// \brief Gets an instance of QA data
+    std::shared_ptr<Data> GetData() { return fpData; }
+
+    /// \brief Initializes the instance and sends the histogram and canvas configuration to the server
+    void Init();
+
+    /// \brief Sends a collection of histograms to the server
+    /// \note  Resets the histograms after sending them
+    void SendHistograms();
+
+    /// \brief Sets a timeslice index
+    /// \param timesliceId  A timeslice index
+    void SetTimesliceId(uint64_t timesliceId) { fpData->SetTimesliceId(timesliceId); }
+
+   private:
+    std::shared_ptr<HistogramSender> fpSender{nullptr};      ///< Histogram sender
+    std::shared_ptr<Data> fpData{std::make_shared<Data>()};  ///< Instance of QA Data
+  };
+}  // namespace cbm::algo::qa
diff --git a/algo/qa/TaskProperties.h b/algo/qa/TaskProperties.h
index 377be8d7777bc2e26e5b10afd7a77eb96bed8dde..ec012b907cd9e29c41cebfc4e9e53ded7272b451 100644
--- a/algo/qa/TaskProperties.h
+++ b/algo/qa/TaskProperties.h
@@ -20,7 +20,7 @@ namespace cbm::algo::qa
   /// \struct HistogramContainer
   /// \brief  Structure to keep the histograms for sending them on the histogram server
   struct TaskProperties {
-    template <class H>
+    template<class H>
     using IteratorPair_t = std::pair<typename std::forward_list<H>::iterator, typename std::forward_list<H>::iterator>;
 
     std::string fsName;                   ///< Name of the task
@@ -30,4 +30,3 @@ namespace cbm::algo::qa
     IteratorPair_t<qa::Prof2D> fRangeP2;  ///< A pair (begin, end) for 2D-profiles in the task
   };
 }  // namespace cbm::algo::qa
-
diff --git a/services/histserv/app/CMakeLists.txt b/services/histserv/app/CMakeLists.txt
index 1435a08a01fb108180571d30f0f8f74592a05809..7a8ebfe9f87dbd248508267785f09f0fcd21734e 100644
--- a/services/histserv/app/CMakeLists.txt
+++ b/services/histserv/app/CMakeLists.txt
@@ -28,7 +28,7 @@ add_executable(histserv_nofairmq ${SRCS} ${HEADERS})
 
 target_link_libraries(histserv_nofairmq
   PUBLIC
-    Algo
+    AlgoOffline
     CbmQaBase
     CbmFlibFlesTools
     CbmServicesHistServ