diff --git a/macro/run/run_unpack_tsa.C b/macro/run/run_unpack_tsa.C
index 6c09f31f6b9117f66478f304e54463344f728612..f5f0d3815436dfcc03d38ef307f3399e5bef11c1 100644
--- a/macro/run/run_unpack_tsa.C
+++ b/macro/run/run_unpack_tsa.C
@@ -26,6 +26,7 @@
 
 std::shared_ptr<CbmTrdUnpackMonitor> GetTrdMonitor(std::string treefilename);
 std::shared_ptr<CbmTrdSpadic> GetTrdSpadic(bool useAvgBaseline = false);
+std::shared_ptr<CbmStsUnpackMonitor> GetStsMonitor(std::string treefilename);
 
 void run_unpack_tsa(std::string infile = "test.tsa", UInt_t runid = 0, const char* setupName = "mcbm_beam_2021_03",
                     std::int32_t nevents = -1, std::string outpath = "")
@@ -119,6 +120,7 @@ void run_unpack_tsa(std::string infile = "test.tsa", UInt_t runid = 0, const cha
     stsconfig->SetDoWriteOutput();
     std::string parfilesbasepathSts = Form("%s/macro/beamtime/mcbm2021/", srcDir.Data());
     stsconfig->SetParFilesBasePath(parfilesbasepathSts);
+    stsconfig->SetMonitor(GetStsMonitor(outfilename));
     stsconfig->SetSystemTimeOffset(-2221);  // [ns] value to be updated
   }
   // -------------
@@ -301,6 +303,7 @@ std::shared_ptr<CbmTrdUnpackMonitor> GetTrdMonitor(std::string treefilename)
   return monitor;
 }
 
+
 /**
  * @brief Get the Trd Spadic
  * @return std::shared_ptr<CbmTrdSpadic>
@@ -313,3 +316,40 @@ std::shared_ptr<CbmTrdSpadic> GetTrdSpadic(bool useAvgBaseline)
 
   return spadic;
 }
+
+/**
+ * @brief Get the Sts Monitor. Extra function to keep default macro part more silent.
+ * @return std::shared_ptr<CbmStsUnpackMonitor>
+*/
+std::shared_ptr<CbmStsUnpackMonitor> GetStsMonitor(std::string treefilename)
+{
+  // -----   Output filename and path   -------------------------------------
+  std::string outpath  = "";
+  std::string filename = "";
+  auto filenamepos     = treefilename.find_last_of("/");
+  if (filenamepos != treefilename.npos) {
+    outpath  = treefilename.substr(0, filenamepos);
+    filename = treefilename.substr(filenamepos++);
+  }
+  if (outpath.empty()) outpath = gSystem->GetWorkingDirectory();
+  std::string mydir = "/qa";
+  outpath += mydir;
+
+  auto currentdir = gSystem->GetWorkingDirectory();
+
+  if (!gSystem->cd(outpath.data())) gSystem->MakeDirectory(outpath.data());
+  else
+    gSystem->cd(currentdir.data());
+
+  std::string outfilename = outpath + filename;
+  auto filetypepos        = outfilename.find(".digi.root");
+  if (filetypepos != outfilename.npos) outfilename.replace(filetypepos, 10, ".mon.sts.root");
+  else
+    outfilename += ".mon.sts.root";
+  // ------------------------------------------------------------------------
+
+  auto monitor = std::make_shared<CbmStsUnpackMonitor>();
+  monitor->SetHistoFileNameFull(outfilename);
+  //monitor->SetDebugMode(true);
+  return monitor;
+}
diff --git a/reco/detectors/sts/unpack/CbmStsUnpackAlgo.cxx b/reco/detectors/sts/unpack/CbmStsUnpackAlgo.cxx
index 8bc5076f921b223a488b05d53fb8691eca373e68..d9e52e169bd8740875fc468a48bf9c71918504e8 100644
--- a/reco/detectors/sts/unpack/CbmStsUnpackAlgo.cxx
+++ b/reco/detectors/sts/unpack/CbmStsUnpackAlgo.cxx
@@ -242,7 +242,6 @@ Bool_t CbmStsUnpackAlgo::initParSet(CbmMcbm2018StsPar* parset)
   LOG(debug) << "Unpacking data in bin sorter FW mode";
   initInternalStatus(parset);
 
-
   return kTRUE;
 }
 
@@ -696,6 +695,7 @@ bool CbmStsUnpackAlgo::unpack(const fles::Timeslice* ts, std::uint16_t icomp, UI
       const double dMsTime = (1e-9) * static_cast<double>(fMsStartTime);
       if (icomp < fMonitor->GetMaxNbFlibLinks()) {
         if (fdStartTimeMsSz < 0) fdStartTimeMsSz = dMsTime;
+        fMonitor->CreateMsComponentSizeHistos(icomp);
         fMonitor->FillMsSize(icomp, uSize);
         fMonitor->FillMsSizeTime(icomp, dMsTime - fdStartTimeMsSz, uSize);
       }
@@ -749,7 +749,7 @@ bool CbmStsUnpackAlgo::unpack(const fles::Timeslice* ts, std::uint16_t icomp, UI
 
   //Output debugging info
   /** @todo @experts this is printout debugging which depends on monitor settings. Not sure whether this is a good way. Please check and decide. (It was this way already before to be clear) */
-  if (fMonitor)
+  if (fMonitor) {
     if (fMonitor->GetDebugMode()) {
       if (18967040000 == fMsStartTime || 18968320000 == fMsStartTime) { LOG(debug) << sMessPatt; }
       if (static_cast<uint16_t>(fles::MicrosliceFlags::CrcValid) != msDescriptor.flags) {
@@ -764,8 +764,13 @@ bool CbmStsUnpackAlgo::unpack(const fles::Timeslice* ts, std::uint16_t icomp, UI
                    << (!bError && 400 != vNbMessType[1]);
       }
     }
+    for (auto itHit = fOutputVec.begin(); itHit != fOutputVec.end(); ++itHit) {
+      fMonitor->FillDigisTimeInRun(itHit->GetTime());
+    }
+    fMonitor->FillVectorSize(ts->index(), fOutputVec.size());
+    //fMonitor->DrawCanvases();
+  }
   return true;
 }
 
-
 ClassImp(CbmStsUnpackAlgo)
diff --git a/reco/detectors/sts/unpack/CbmStsUnpackAlgo.h b/reco/detectors/sts/unpack/CbmStsUnpackAlgo.h
index 502e9b4c273e40a0ca3130d42a53d94b7e8ec40a..c35e3ba8260e1495cbc08c580a289f623ad906eb 100644
--- a/reco/detectors/sts/unpack/CbmStsUnpackAlgo.h
+++ b/reco/detectors/sts/unpack/CbmStsUnpackAlgo.h
@@ -89,7 +89,7 @@ protected:
   /** @brief Finish function for this algorithm base clase */
   void finish()
   {
-    // if (fMonitor) fMonitor->Finish();
+    if (fMonitor) fMonitor->Finish();
     return;
   }
 
@@ -267,7 +267,6 @@ protected:
   /** @brief Vector of channel masks, [ NbFeb ][ NbCHanInFeb ], used only if fbUseChannelMask is true */
   std::vector<std::vector<bool>> fvvbMaskedChannels = {};  //!
 
-
   /** @brief  FEB type, [ NbDpb ][ NbCrobPerDpb ][ NbFebsPerCrob ], 0 = A, 1 = B, -1 if inactive */
   std::vector<std::vector<std::vector<int32_t>>> fviFebType = {};  //!
 
diff --git a/reco/detectors/sts/unpack/CbmStsUnpackConfig.cxx b/reco/detectors/sts/unpack/CbmStsUnpackConfig.cxx
index 48fdc0927f54524f7a25ef42b4931df28a163180..513cf2a0632e9330906bcc0a596a0b9e60b5f3c1 100644
--- a/reco/detectors/sts/unpack/CbmStsUnpackConfig.cxx
+++ b/reco/detectors/sts/unpack/CbmStsUnpackConfig.cxx
@@ -54,7 +54,10 @@ void CbmStsUnpackConfig::InitUnpacker()
   // Now we have all information required to initialise the algorithm
   algo->Init();
 
-  if (fMonitor) algo->SetMonitor(fMonitor);
+  if (fMonitor) {
+    fMonitor->Init(static_cast<CbmMcbm2018StsPar*>(reqparvec->at(0).second.get()));
+    algo->SetMonitor(fMonitor);
+  }
 
   // Pass the algo to its member in the base class
   fAlgo = algo;
diff --git a/reco/detectors/sts/unpack/CbmStsUnpackMonitor.cxx b/reco/detectors/sts/unpack/CbmStsUnpackMonitor.cxx
index d2052233a995b82111684c1583cd88b7d44ef58e..975ea19115341aa9c7bdc3dcb88e9ba565e7c182 100644
--- a/reco/detectors/sts/unpack/CbmStsUnpackMonitor.cxx
+++ b/reco/detectors/sts/unpack/CbmStsUnpackMonitor.cxx
@@ -292,13 +292,13 @@ Bool_t CbmStsUnpackMonitor::CreateMsComponentSizeHistos(UInt_t component)
     TString sMsSizeTitle = Form("Size of MS for nDPB of link %02u; Ms Size [bytes]", component);
     fvhMsSize[component] = new TH1F(sMsSizeName.Data(), sMsSizeTitle.Data(), 30000, 0., 30000.);
     fvhMsSize[component]->SetCanExtend(TH2::kAllAxes);
-
-    sMsSizeName              = Form("MsSizeTime_link_%02u", component);
-    sMsSizeTitle             = Form("Size of MS vs time for gDPB of link %02u; Time[s] ; Ms Size [bytes]", component);
+    AddHistoToVector(fvhMsSize[component], "perComponent");
+  }
+  if (nullptr == fvhMsSizeTime[component]) {
+    TString sMsSizeName      = Form("MsSizeTime_link_%02u", component);
+    TString sMsSizeTitle     = Form("Size of MS vs time for gDPB of link %02u; Time[s] ; Ms Size [bytes]", component);
     fvhMsSizeTime[component] = new TProfile(sMsSizeName.Data(), sMsSizeTitle.Data(), 15000, 0., 300.);
     fvhMsSizeTime[component]->SetCanExtend(TH2::kAllAxes);
-
-    AddHistoToVector(fvhMsSize[component], "perComponent");
     AddHistoToVector(fvhMsSizeTime[component], "perComponent");
   }
   return kTRUE;
@@ -306,10 +306,8 @@ Bool_t CbmStsUnpackMonitor::CreateMsComponentSizeHistos(UInt_t component)
 
 Bool_t CbmStsUnpackMonitor::ResetMsComponentSizeHistos(UInt_t component)
 {
-  if (nullptr == fvhMsSize[component]) {
-    fvhMsSize[component]->Reset();
-    fvhMsSizeTime[component]->Reset();
-  }
+  if (nullptr != fvhMsSize[component]) { fvhMsSize[component]->Reset(); }
+  if (nullptr != fvhMsSizeTime[component]) { fvhMsSizeTime[component]->Reset(); }
   return kTRUE;
 }
 
@@ -678,5 +676,58 @@ Bool_t CbmStsUnpackMonitor::Init(CbmMcbm2018StsPar* parset)
   return kTRUE;
 }
 
+// ---- Finish ----
+void CbmStsUnpackMonitor::Finish()
+{
+  DrawCanvases();
+
+  /// Obtain vector of pointers on each histo (+ optionally desired folder)
+  std::vector<std::pair<TNamed*, std::string>> vHistos = GetHistoVector();
+
+  /// Obtain vector of pointers on each canvas (+ optionally desired folder)
+  std::vector<std::pair<CbmQaCanvas*, std::string>> vCanvases = GetCanvasVector();
+
+  /// 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();
+  }
+
+  /// Write canvases to output file
+  for (UInt_t uCanvas = 0; uCanvas < vCanvases.size(); ++uCanvas) {
+    /// Make sure we end up in chosen folder
+    TString sFolder = vCanvases[uCanvas].second.data();
+    if (nullptr == gDirectory->Get(sFolder)) gDirectory->mkdir(sFolder);
+    gDirectory->cd(sFolder);
+
+    /// Write canvas
+    vCanvases[uCanvas].first->Write();
+
+    histoFile->cd();
+  }
+
+  /// Restore old global file and folder pointer to avoid messing with FairRoot
+  gFile      = oldFile;
+  gDirectory = oldDir;
+
+  histoFile->Close();
+}
+
 
 ClassImp(CbmStsUnpackMonitor)
diff --git a/reco/detectors/sts/unpack/CbmStsUnpackMonitor.h b/reco/detectors/sts/unpack/CbmStsUnpackMonitor.h
index 0811c58b81d8c48f6218eb60b9a88b2f35873d03..29c76af75db5989e3a9b4ee55bcc0fb53fe722ef 100644
--- a/reco/detectors/sts/unpack/CbmStsUnpackMonitor.h
+++ b/reco/detectors/sts/unpack/CbmStsUnpackMonitor.h
@@ -41,6 +41,12 @@ public:
   Bool_t CreateMsComponentSizeHistos(UInt_t component);
   Bool_t ResetMsComponentSizeHistos(UInt_t component);
 
+  /** @brief Write all histograms and canvases to file */
+  void Finish();
+
+  void SetHistoFileName(TString nameIn) { fHistoFileName = "data/" + nameIn + ".root"; }
+  void SetHistoFileNameFull(TString nameIn) { fHistoFileName = nameIn; }
+
   void DrawCanvases();
 
   void AddHistoToVector(TNamed* pointer, std::string sFolder = "")
@@ -209,6 +215,8 @@ public:
   void SetDebugMode(bool value) { fDebugMode = value; }
 
 private:
+  TString fHistoFileName = "data/HistosUnpackerSts.root";
+
   /// Rate evolution histos
   //Bool_t fbLongHistoEnable;
   UInt_t fuLongHistoNbSeconds  = 3600;