diff --git a/reco/detectors/rich/unpack/CbmRichUnpackMonitor.cxx b/reco/detectors/rich/unpack/CbmRichUnpackMonitor.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..d544077605b66dc28f5e19e14b2f9830437636c4
--- /dev/null
+++ b/reco/detectors/rich/unpack/CbmRichUnpackMonitor.cxx
@@ -0,0 +1,166 @@
+/* Copyright (C) 2021 Goethe-University, Frankfurt
+   SPDX-License-Identifier: GPL-3.0-only
+   Authors: Adrian Weber [committer]*/
+
+#include "CbmRichUnpackMonitor.h"
+
+#include "MicrosliceDescriptor.hpp"
+
+#include <FairRun.h>
+#include <FairRunOnline.h>
+#include <Logger.h>
+
+#include <RtypesCore.h>
+#include <TFile.h>
+#include <TH1.h>
+#include <TH2.h>
+#include <THttpServer.h>
+#include <TProfile.h>
+
+#include <cstdint>
+#include <iomanip>
+#include <iostream>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include <cmath>
+
+CbmRichUnpackMonitor::CbmRichUnpackMonitor(/* args */) : vNbMessType(7, 0), fvpAllHistoPointers()
+{
+}
+
+CbmRichUnpackMonitor::~CbmRichUnpackMonitor()
+{
+  for (auto iter = fvpAllHistoPointers.begin(); iter != fvpAllHistoPointers.end();) {
+    if (iter->first != nullptr) { delete iter->first; }
+    iter = fvpAllHistoPointers.erase(iter);
+  }
+}
+
+Bool_t CbmRichUnpackMonitor::CreateHistograms(CbmMcbm2018RichPar* pUnpackPar)
+{
+  TString sHistName {""};
+  TString title {""};
+  //const UInt_t uNbAsics       = pUnpackPar->GetNrOfAsics();
+
+
+  /// Create general unpacking histograms
+  fhDigisTimeInRun = new TH1I("hRichDigisTimeInRun", "Digis Nb vs Time in Run; Time in run [s]; Digis Nb []", 10, 0, 1);
+  fhDigisTimeInRun->SetCanExtend(TH1::kAllAxes);
+  AddHistoToVector(fhDigisTimeInRun, "");
+  
+  fhDigisToT = new TH1F("hDigisToT", "fhDigisToT; ToT [ns]; Entries", 400, 0, 40.);
+  fhDigisTimeInRun->SetCanExtend(TH1::kAllAxes);
+  AddHistoToVector(fhDigisToT, "");  
+
+  fhVectorSize = new TH1I("fhVectorSize", "Size of the vector VS TS index; TS index; Size [bytes]", 10, 0, 10);
+  fhVectorSize->SetCanExtend(TH1::kAllAxes);
+  AddHistoToVector(fhVectorSize, "");
+
+  fhVectorCapacity =
+    new TH1I("fhVectorCapacity", "Size of the vector VS TS index; TS index; Size [bytes]", 10000, 0., 10000.);
+  AddHistoToVector(fhVectorCapacity, "");
+
+  return kTRUE;
+}
+
+
+Bool_t CbmRichUnpackMonitor::ResetHistograms()
+{
+  fhDigisTimeInRun->Reset();
+  fhVectorSize->Reset();
+  fhVectorCapacity->Reset();
+
+  return kTRUE;
+}
+
+Bool_t CbmRichUnpackMonitor::CreateDebugHistograms(CbmMcbm2018RichPar* pUnpackPar)
+{
+  return kTRUE;
+}
+
+Bool_t CbmRichUnpackMonitor::ResetDebugHistograms()
+{
+  return kTRUE;
+}
+// -------------------------------------------------------------------------
+
+
+// -------------------------------------------------------------------------
+void CbmRichUnpackMonitor::FillPerTimesliceCountersHistos(double_t dTsStartTimeS)
+{
+  if (0 == dFirstTsStartTime) dFirstTsStartTime = dTsStartTimeS;
+  double_t dTimeInRun     = dTsStartTimeS - dFirstTsStartTime;
+  double_t dRatio         = 0;
+}
+
+
+// -------------------------------------------------------------------------
+void CbmRichUnpackMonitor::PrintDebugInfo(const uint64_t MsStartTime, const size_t NrProcessedTs,
+                                         const uint16_t msDescriptorFlags, const uint32_t uSize)
+{
+}
+
+// ---- Init ----
+Bool_t CbmRichUnpackMonitor::Init(CbmMcbm2018RichPar* parset)
+{
+  /// Trigger histo creation on all associated monitors
+  CreateHistograms(parset);
+  if (fDebugMode) CreateDebugHistograms(parset);
+
+  /// Obtain vector of pointers on each histo from the algo (+ optionally desired folder)
+  std::vector<std::pair<TNamed*, std::string>> vHistos = GetHistoVector();
+
+  /// Register the histos in the HTTP server
+  THttpServer* server = FairRunOnline::Instance()->GetHttpServer();
+  if (nullptr != server) {
+    for (UInt_t uHisto = 0; uHisto < vHistos.size(); ++uHisto) {
+      server->Register(Form("/%s", vHistos[uHisto].second.data()), vHistos[uHisto].first);
+    }
+    server->RegisterCommand("/Reset_UnpRich_Hist", "bMcbm2018UnpackerTaskRichResetHistos=kTRUE");
+    server->Restrict("/Reset_UnpRich_Hist", "allow=admin");
+  }
+
+  return kTRUE;
+}
+
+// ---- Finish ----
+void CbmRichUnpackMonitor::Finish()
+{
+
+  /// Obtain vector of pointers on each histo (+ optionally desired folder)
+  std::vector<std::pair<TNamed*, std::string>> vHistos = GetHistoVector();
+
+  /// Save old global file and folder pointer to avoid messing with FairRoot
+  TFile* oldFile     = gFile;
+  TDirectory* oldDir = gDirectory;
+  TFile* histoFile   = nullptr;
+
+  // open separate histo file in recreate mode
+  histoFile = new TFile(fHistoFileName, "RECREATE");
+  histoFile->cd();
+  
+  /// Write histos to output file
+  for (UInt_t uHisto = 0; uHisto < vHistos.size(); ++uHisto) {
+    /// Make sure we end up in chosen folder
+    TString sFolder = vHistos[uHisto].second.data();
+    if (nullptr == gDirectory->Get(sFolder)) gDirectory->mkdir(sFolder);
+    gDirectory->cd(sFolder);
+
+    /// Write plot
+    vHistos[uHisto].first->Write();
+
+    histoFile->cd();
+  }
+
+  /// Restore old global file and folder pointer to avoid messing with FairRoot
+  gFile      = oldFile;
+  gDirectory = oldDir;
+
+  histoFile->Close();
+  delete histoFile;
+}
+
+
+ClassImp(CbmRichUnpackMonitor)
diff --git a/reco/detectors/rich/unpack/CbmRichUnpackMonitor.h b/reco/detectors/rich/unpack/CbmRichUnpackMonitor.h
new file mode 100644
index 0000000000000000000000000000000000000000..2b1bd29168c54e0e00230bc2e8183e4966ee7cb2
--- /dev/null
+++ b/reco/detectors/rich/unpack/CbmRichUnpackMonitor.h
@@ -0,0 +1,105 @@
+/* Copyright (C) 2021 Goethe-University, Frankfurt
+   SPDX-License-Identifier: GPL-3.0-only
+   Authors: Adrian Weber [commiter]*/
+
+#ifndef CbmRichUnpackMonitor_H
+#define CbmRichUnpackMonitor_H
+
+#include "CbmMcbm2018RichPar.h"
+
+#include "Rtypes.h"
+#include "TH1.h"
+#include "TH2.h"
+
+#include <cstdint>
+
+class CbmRichUnpackMonitor {
+public:
+  CbmRichUnpackMonitor();
+
+  virtual ~CbmRichUnpackMonitor();
+
+  //Variables for debugging info
+  std::vector<uint32_t> vNbMessType;
+  std::string sMessPatt = "";
+  bool bError           = false;
+
+  void ResetDebugInfo();
+  void PrintDebugInfo(const uint64_t MsStartTime, const size_t NrProcessedTs, const uint16_t msDescriptorFlags,
+                      const uint32_t uSize);
+
+  /** @brief Init all required parameter informations and histograms */
+  Bool_t Init(CbmMcbm2018RichPar* parset);
+
+  Bool_t CreateHistograms(CbmMcbm2018RichPar* pUnpackPar);
+  Bool_t ResetHistograms();
+
+  Bool_t CreateDebugHistograms(CbmMcbm2018RichPar* pUnpackPar);
+  Bool_t ResetDebugHistograms();
+
+
+  /** @brief Write all histograms to file */
+  void Finish();
+
+  void SetHistoFileName(TString nameIn) { fHistoFileName = nameIn; }
+
+  void AddHistoToVector(TNamed* pointer, std::string sFolder = "")
+  {
+    fvpAllHistoPointers.push_back(std::pair<TNamed*, std::string>(pointer, sFolder));
+  }
+  std::vector<std::pair<TNamed*, std::string>> GetHistoVector() { return fvpAllHistoPointers; }
+
+
+  ///Fill general histograms
+  void FillVectorSize(ULong64_t TsIdx, UInt_t Size) { fhVectorSize->Fill(TsIdx, Size); }
+  void FillVectorCapacity(ULong64_t TsIdx, UInt_t Capacity) { fhVectorCapacity->Fill(TsIdx, Capacity); }
+  
+  void FillDigisTimeInRun(Double_t Time) { fhDigisTimeInRun->Fill(Time * 1e-9); }
+  
+  void FillDigisToT(Double_t ToT) { fhDigisToT->Fill(ToT); }
+
+  void FillPerTimesliceCountersHistos(double_t dTsStartTime);
+
+  /** @brief Activate the debug mode */
+  bool GetDebugMode() { return fDebugMode; }
+
+  /** @brief Activate the debug mode */
+  void SetDebugMode(bool value) { fDebugMode = value; }
+
+private:
+  TString fHistoFileName = "HistosUnpackerRich.root";
+
+  
+  double_t dFirstTsStartTime = 0;
+
+  ///General histograms
+  TH1* fhDigisTimeInRun         = nullptr;
+  TH1* fhDigisToT               = nullptr;
+  TH1* fhVectorSize             = nullptr;
+  TH1* fhVectorCapacity         = nullptr;
+
+  /** @brief Flag if debug mode is active or not */
+  bool fDebugMode = false;
+
+
+  /// For monitoring of internal processes.
+  /// => Pointers should be filled with TH1*, TH2*, TProfile*, ...
+  /// ==> To check if object N is of type T, use "T ObjectPointer = dynamic_cast<T>( fvpAllHistoPointers[N].first );" and check for nullptr
+  /// ==> To get back the original class name use "fvpAllHistoPointers[N].first->ClassName()" which returns a const char * (e.g. "TH1I")
+  /// ===> Usage example with feeding a THttpServer:
+  /// ===> #include "TH2.h"
+  /// ===> std::string sClassName = vHistos[ uHisto ].first.ClassName();
+  /// ===> if( !strncmp( sClassName, "TH1", 3 ) )
+  /// ===>    server->Register( vHistos[ uHisto ].second.data(), dynamic_cast< TH1 * >(vHistos[ uHisto ].first) );
+  /// ===> else if( !strncmp( sClassName, "TH2", 3 ) )
+  /// ===>    server->Register( vHistos[ uHisto ].second.data(), dynamic_cast< TH2 * >(vHistos[ uHisto ].first) );
+  std::vector<std::pair<TNamed*, std::string>>
+    fvpAllHistoPointers;  //! Vector of pointers to histograms + optional folder name
+
+  CbmRichUnpackMonitor(const CbmRichUnpackMonitor&);
+  CbmRichUnpackMonitor operator=(const CbmRichUnpackMonitor&);
+
+  ClassDef(CbmRichUnpackMonitor, 1)
+};
+
+#endif