diff --git a/algo/CMakeLists.txt b/algo/CMakeLists.txt
index 3790983c8a3d1fee99bd2a0c885ca2b8f89aa3a3..c96bac5cfd7e22bfbfd14264e36675385d6030e1 100644
--- a/algo/CMakeLists.txt
+++ b/algo/CMakeLists.txt
@@ -72,7 +72,9 @@ set(SRCS
   base/DigiData.cxx
   base/Options.cxx
   base/MainConfig.cxx
+  base/RecoParams.cxx
   base/util/TimingsFormat.cxx
+  data/sts/HitfinderPars.cxx
   data/sts/LandauTable.cxx
   evbuild/Config.cxx
   evbuild/EventBuilder.cxx
@@ -83,6 +85,7 @@ set(SRCS
   evselector/DigiEventSelector.cxx
   evselector/DigiEventSelectorConfig.cxx
   unpack/CommonUnpacker.cxx
+  detectors/sts/ChannelMaskSet.cxx
   detectors/sts/ChannelMaskSet_mCBM2022.cxx
   detectors/sts/ReadoutConfig.cxx
   detectors/sts/ReadoutConfig_mCBM2022.cxx
@@ -116,6 +119,8 @@ set(SRCS
   detectors/rich/Unpack.cxx
   detectors/rich/UnpackMS.cxx
   global/Reco.cxx
+  global/RecoResultsInputArchive.cxx
+  global/RecoResultsOutputArchive.cxx
   qa/DigiEventQa.cxx
   qa/Histo1D.cxx
   qa/CanvasConfig.cxx
diff --git a/algo/base/RecoParams.cxx b/algo/base/RecoParams.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..851df115fa80ce0a11cc589f403a6c75ee38ae8f
--- /dev/null
+++ b/algo/base/RecoParams.cxx
@@ -0,0 +1,6 @@
+/* Copyright (C) 2024 FIAS Frankfurt Institute for Advanced Studies, Frankfurt / Main
+   SPDX-License-Identifier: GPL-3.0-only
+   Authors: Felix Weiglhofer [committer] */
+#include "RecoParams.h"
+
+CBM_YAML_INSTANTIATE(cbm::algo::RecoParams);
diff --git a/algo/base/RecoParams.h b/algo/base/RecoParams.h
index d51fdbef8f393dc569f8b013cc577ca8560d1d3a..22a01f3769bc4b01856eb45e25e0afc3b62350ea 100644
--- a/algo/base/RecoParams.h
+++ b/algo/base/RecoParams.h
@@ -6,6 +6,7 @@
 
 #include "Definitions.h"
 #include "config/Property.h"
+#include "config/Yaml.h"
 #include "util/EnumDict.h"
 
 #include <xpu/defines.h>
@@ -95,6 +96,8 @@ namespace cbm::algo
 
 }  // namespace cbm::algo
 
+CBM_YAML_EXTERN_DECL(cbm::algo::RecoParams);
+
 CBM_ENUM_DICT(cbm::algo::RecoParams::SortMode,
   {"BlockSort", RecoParams::SortMode::BlockSort},
   {"CUBSegmentedSort", RecoParams::SortMode::CUBSegmentedSort}
diff --git a/algo/base/config/Yaml.h b/algo/base/config/Yaml.h
index c73124ef14954c4ec02fff61ced6320b493322bd..d7b5d5c0c3d00c6eae45c65593f096fd1babb168 100644
--- a/algo/base/config/Yaml.h
+++ b/algo/base/config/Yaml.h
@@ -55,9 +55,19 @@ namespace cbm::algo::config
     return Read<T>(node);
   }
 
+
   template<typename T>
   T Read(const YAML::Node& node)
   {
+// Disable uninitialized warning for the whole function.
+// GCC 11.4 sometimes incorrectly warns about uninitialized variables in constexpr if branches.
+// I'm fairly certain this is a compiler bug, because it only happens when
+// explicitly instantiating the function template. And the error message
+// references a variable 't' that doesn't exist in the function!
+#if defined(__GNUC__) && !defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#endif
     using Type = std::remove_cv_t<std::remove_reference_t<T>>;
 
     static_assert(!IsEnum<T> || detail::EnumHasDict_v<T>, "Enum must have a dictionary to be deserializable");
@@ -102,7 +112,7 @@ namespace cbm::algo::config
 
       static_assert(IsScalar<Key_t>, "Map key must be a fundamental or enum type");
 
-      Type map;
+      Type map{};
       for (YAML::const_iterator it = node.begin(); it != node.end(); ++it) {
         const auto& key       = it->first;
         const auto& value     = it->second;
@@ -111,7 +121,7 @@ namespace cbm::algo::config
       return map;
     }
     else {
-      Type object;
+      Type object{};
 
       constexpr auto nProperties = std::tuple_size<decltype(Type::Properties)>::value;
 
@@ -132,6 +142,10 @@ namespace cbm::algo::config
 
       return object;
     }
+
+#if defined(__GNUC__) && !defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
   }
 
   template<typename T>
@@ -202,15 +216,28 @@ namespace cbm::algo::config
           ss << object;
       }
       else if constexpr (IsEnum<T>) {
-        ss << ToString<T>(object);
+        ss << std::string{ToString<T>(object)};
       }
       else if constexpr (IsVector<T> || IsArray<T> || IsSet<T>) {
         ss << YAML::BeginSeq;
-        for (const auto& element : object) {
-          if (formatEntries.has_value()) {
-            ss << formatEntries.value();
+        // Special case for vector<bool> because it is not a real vector
+        // Clang does not the compile the generic version of the loop
+        // in this case.
+        if constexpr (std::is_same_v<T, std::vector<bool>>) {
+          for (bool element : object) {
+            if (formatEntries.has_value()) {
+              ss << formatEntries.value();
+            }
+            ss << element;
+          }
+        }
+        else {
+          for (const auto& element : object) {
+            if (formatEntries.has_value()) {
+              ss << formatEntries.value();
+            }
+            DoDump(element, ss);
           }
-          DoDump(element, ss);
         }
         ss << YAML::EndSeq;
       }
@@ -262,4 +289,22 @@ namespace cbm::algo::config
 
 }  // namespace cbm::algo::config
 
+/**
+ * @brief Declare the external instantiation of the Read and Dump functions for a type.
+ * @param type The type to declare the external instantiation for.
+ * @note This macro should be used in a header file to declare the external instantiation of the Read and Dump.
+ * Must be paired with CBM_YAML_INSTANTIATE in a source file.
+ **/
+#define CBM_YAML_EXTERN_DECL(type)                                                                                     \
+  extern template type cbm::algo::config::Read<type>(const YAML::Node& node);                                          \
+  extern template std::string cbm::algo::config::Dump::operator()<type>(const type& value, int floatPrecision)
+
+/**
+ * @brief Explicitly instantiate the Read and Dump functions for a type.
+ * @see CBM_YAML_EXTERN_DECL
+ */
+#define CBM_YAML_INSTANTIATE(type)                                                                                     \
+  template type cbm::algo::config::Read<type>(const YAML::Node& node);                                                 \
+  template std::string cbm::algo::config::Dump::operator()<type>(const type& value, int floatPrecision);
+
 #endif
diff --git a/algo/ca/core/tracking/CaCloneMerger.h b/algo/ca/core/tracking/CaCloneMerger.h
index c16d53fe4fed6220d2552f287f0633d05128f31c..0cef1c285d5efcb5c2c164d7a305fd68cd11162d 100644
--- a/algo/ca/core/tracking/CaCloneMerger.h
+++ b/algo/ca/core/tracking/CaCloneMerger.h
@@ -11,6 +11,7 @@
 
 #include "CaHit.h"   // For ca::HitIndex_t
 #include "CaSimd.h"  // TEMPORARY FOR fvec, fscal
+#include "CaTrack.h"
 #include "CaVector.h"
 
 
diff --git a/algo/data/sts/HitfinderPars.cxx b/algo/data/sts/HitfinderPars.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..ac6fe3baca23ba494fd720cc113209b1914451d2
--- /dev/null
+++ b/algo/data/sts/HitfinderPars.cxx
@@ -0,0 +1,8 @@
+/* Copyright (C) 2024 FIAS Frankfurt Institute for Advanced Studies, Frankfurt / Main
+   SPDX-License-Identifier: GPL-3.0-only
+   Authors: Felix Weiglhofer [committer] */
+
+#include "HitfinderPars.h"
+
+using namespace cbm::algo;
+CBM_YAML_INSTANTIATE(sts::HitfinderPars);
diff --git a/algo/data/sts/HitfinderPars.h b/algo/data/sts/HitfinderPars.h
index 84e99607ed189a6dd419cb19b0d37173431086e1..b0923900ec5a918448881e0767e196903b1c3693 100644
--- a/algo/data/sts/HitfinderPars.h
+++ b/algo/data/sts/HitfinderPars.h
@@ -1,12 +1,14 @@
 /* Copyright (C) 2023 FIAS Frankfurt Institute for Advanced Studies, Frankfurt / Main
    SPDX-License-Identifier: GPL-3.0-only
    Authors: Felix Weiglhofer [committer] */
-#ifndef CBM_ALGO_DATA_STS_HITFINDERPARS_H
-#define CBM_ALGO_DATA_STS_HITFINDERPARS_H
+#pragma once
 
 #include "Definitions.h"
 #include "LandauTable.h"
 #include "config/Property.h"
+#include "config/Yaml.h"
+
+#include <xpu/defines.h>
 
 namespace cbm::algo::sts
 {
@@ -78,4 +80,4 @@ namespace cbm::algo::sts
   };
 }  // namespace cbm::algo::sts
 
-#endif
+CBM_YAML_EXTERN_DECL(cbm::algo::sts::HitfinderPars);
diff --git a/algo/detectors/sts/ChannelMaskSet.cxx b/algo/detectors/sts/ChannelMaskSet.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..10dce9224e8fbcaeb057922940e4a31f22ff67d6
--- /dev/null
+++ b/algo/detectors/sts/ChannelMaskSet.cxx
@@ -0,0 +1,8 @@
+/* Copyright (C) 2024 FIAS Frankfurt Institute for Advanced Studies, Frankfurt / Main
+   SPDX-License-Identifier: GPL-3.0-only
+   Authors: Felix Weiglhofer [committer], Dominik Smith */
+
+#include "ChannelMaskSet.h"
+
+using namespace cbm::algo;
+CBM_YAML_INSTANTIATE(sts::ChannelMaskSet);
diff --git a/algo/detectors/sts/ChannelMaskSet.h b/algo/detectors/sts/ChannelMaskSet.h
index 0523eaec5e8b6584fdf87a2dd723d577a3e28938..aab508cee3e8153b17b76a36ecc6d7915ae4981d 100644
--- a/algo/detectors/sts/ChannelMaskSet.h
+++ b/algo/detectors/sts/ChannelMaskSet.h
@@ -7,6 +7,7 @@
 #include "Definitions.h"
 #include "compat/Filesystem.h"
 #include "config/Property.h"
+#include "config/Yaml.h"
 
 #include <map>
 #include <set>
@@ -49,3 +50,5 @@ namespace cbm::algo::sts
   };
 
 }  // namespace cbm::algo::sts
+
+CBM_YAML_EXTERN_DECL(cbm::algo::sts::ChannelMaskSet);
diff --git a/algo/detectors/sts/ReadoutConfig.cxx b/algo/detectors/sts/ReadoutConfig.cxx
index c50ef025b1ce2f0f96660a96a8192df3e83e8972..1d08012559e01831e9d36b3e7d9fd58bae0de341 100644
--- a/algo/detectors/sts/ReadoutConfig.cxx
+++ b/algo/detectors/sts/ReadoutConfig.cxx
@@ -14,6 +14,8 @@ using std::setw;
 
 using namespace cbm::algo;
 
+CBM_YAML_INSTANTIATE(sts::ReadoutSetup);
+
 sts::ReadoutConfig::ReadoutConfig(const ReadoutSetup& config, const ChannelMaskSet& chanMaskSet)
 {
   Init(config, chanMaskSet);
diff --git a/algo/detectors/sts/ReadoutConfig.h b/algo/detectors/sts/ReadoutConfig.h
index 23366c8dc80902117ce4e908f5d0f167d5a9e2d1..324b3efca0ea76447d9619060a3059acb9cbf334 100644
--- a/algo/detectors/sts/ReadoutConfig.h
+++ b/algo/detectors/sts/ReadoutConfig.h
@@ -6,6 +6,7 @@
 
 #include "Definitions.h"
 #include "config/Property.h"
+#include "config/Yaml.h"
 
 #include <map>
 #include <string>
@@ -161,4 +162,6 @@ namespace cbm::algo::sts
 
 }  // namespace cbm::algo::sts
 
+CBM_YAML_EXTERN_DECL(cbm::algo::sts::ReadoutSetup);
+
 #endif  // CBM_ALGO_DETECTOR_STS_READOUT_CONFIG_H
diff --git a/algo/detectors/sts/WalkMap.cxx b/algo/detectors/sts/WalkMap.cxx
index e1ab3a314ddca46c1423ee20e79eea410c4cb845..e97620a5d679afc29cd34e5c6ea9bf9917745a55 100644
--- a/algo/detectors/sts/WalkMap.cxx
+++ b/algo/detectors/sts/WalkMap.cxx
@@ -6,6 +6,8 @@
 
 using namespace cbm::algo::sts;
 
+CBM_YAML_INSTANTIATE(WalkMap);
+
 std::vector<double> WalkMap::Get(int32_t modAddress, uint16_t asic)
 {
   std::vector<double> result;
diff --git a/algo/detectors/sts/WalkMap.h b/algo/detectors/sts/WalkMap.h
index 139a8d985e12ec60f300d25eff51cf06906225a5..04fcc7df317e03f072c9f95cc510f39fb2705ec9 100644
--- a/algo/detectors/sts/WalkMap.h
+++ b/algo/detectors/sts/WalkMap.h
@@ -6,6 +6,7 @@
 
 #include "Definitions.h"
 #include "config/Property.h"
+#include "config/Yaml.h"
 
 #include <map>
 #include <vector>
@@ -57,3 +58,5 @@ namespace cbm::algo::sts
   };
 
 }  // namespace cbm::algo::sts
+
+CBM_YAML_EXTERN_DECL(cbm::algo::sts::WalkMap);
diff --git a/algo/detectors/trd/ReadoutConfig.cxx b/algo/detectors/trd/ReadoutConfig.cxx
index 1a462bbfa44859f309637b87e875a8b4bfc9747d..828665b6ff2e3ddf0d609db33404904c56f24873 100644
--- a/algo/detectors/trd/ReadoutConfig.cxx
+++ b/algo/detectors/trd/ReadoutConfig.cxx
@@ -14,6 +14,8 @@
 using std::pair;
 using std::setw;
 
+CBM_YAML_INSTANTIATE(cbm::algo::trd::ReadoutConfig);
+
 namespace cbm::algo::trd
 {
 
diff --git a/algo/detectors/trd/ReadoutConfig.h b/algo/detectors/trd/ReadoutConfig.h
index 98528a7fbd34a1e7ef2cdf0c89f2a676de13cba8..b8730f47b6486150e66ee6dc32df282a26abc0ef 100644
--- a/algo/detectors/trd/ReadoutConfig.h
+++ b/algo/detectors/trd/ReadoutConfig.h
@@ -2,10 +2,10 @@
    SPDX-License-Identifier: GPL-3.0-only
    Authors: Volker Friese [committer] */
 
-#ifndef ALGO_DETECTORS_TRD_READOUTCONFIG_H
-#define ALGO_DETECTORS_TRD_READOUTCONFIG_H
+#pragma once
 
 #include "config/Property.h"
+#include "config/Yaml.h"
 
 #include <map>
 #include <sstream>
@@ -36,7 +36,7 @@ namespace cbm::algo::trd
 
 
     /** @brief Destructor **/
-    virtual ~ReadoutConfig();
+    ~ReadoutConfig();
 
 
     /** @brief Equipment in the configuration
@@ -92,4 +92,4 @@ namespace cbm::algo::trd
 
 }  // namespace cbm::algo::trd
 
-#endif /* ALGO_DETECTORS_TRD_READOUTCONFIG_H_ */
+CBM_YAML_EXTERN_DECL(cbm::algo::trd::ReadoutConfig);
diff --git a/algo/detectors/trd/UnpackMS.cxx b/algo/detectors/trd/UnpackMS.cxx
index 72b6f7ab593316d405541e4d673cc149be043839..1ae1f29bf267157eb9fb0c7d5a69d97a2a5aa7a9 100644
--- a/algo/detectors/trd/UnpackMS.cxx
+++ b/algo/detectors/trd/UnpackMS.cxx
@@ -6,6 +6,7 @@
 
 #include <algorithm>
 #include <cassert>
+#include <log.hpp>
 #include <vector>
 
 using std::unique_ptr;
@@ -335,8 +336,8 @@ namespace cbm::algo::trd
       return Spadic::MsInfoType::kMIS;
     }
     else {
-      std::cout << "UnpackMS::GetInfoType] unknown type!" << std::endl;
-      exit(1);
+      // TODO: track this error
+      L_(error) << "UnpackMS::GetInfoType] unknown type!";
       return Spadic::MsInfoType::kMSB;
     }
   }
diff --git a/algo/detectors/trd2d/ReadoutConfig.cxx b/algo/detectors/trd2d/ReadoutConfig.cxx
index 067f7b1fe0f859920d2a37bbf7669a65c83f5616..3aaa79b1c208c9bcd6078d5c090b2561702f6eb2 100644
--- a/algo/detectors/trd2d/ReadoutConfig.cxx
+++ b/algo/detectors/trd2d/ReadoutConfig.cxx
@@ -14,6 +14,8 @@
 using std::pair;
 using std::setw;
 
+CBM_YAML_INSTANTIATE(cbm::algo::trd2d::ReadoutConfig);
+
 namespace cbm::algo::trd2d
 {
 
diff --git a/algo/detectors/trd2d/ReadoutConfig.h b/algo/detectors/trd2d/ReadoutConfig.h
index a672169c6025480ee0d7ca661040164572ffcf4b..6942caa9bc9652a426831206a023908057299aa8 100644
--- a/algo/detectors/trd2d/ReadoutConfig.h
+++ b/algo/detectors/trd2d/ReadoutConfig.h
@@ -2,11 +2,11 @@
    SPDX-License-Identifier: GPL-3.0-only
    Authors: Volker Friese, Dominik Smith [committer] */
 
-#ifndef ALGO_DETECTORS_TRD2D_READOUTCONFIG_H
-#define ALGO_DETECTORS_TRD2D_READOUTCONFIG_H
+#pragma once
 
 #include "UnpackMS.h"
 #include "config/Property.h"
+#include "config/Yaml.h"
 
 #include <map>
 #include <sstream>
@@ -57,7 +57,7 @@ namespace cbm::algo::trd2d
 
 
     /** @brief Destructor **/
-    virtual ~ReadoutConfig();
+    ~ReadoutConfig();
 
 
     /** @brief Equipment in the configuration
@@ -126,4 +126,4 @@ namespace cbm::algo::trd2d
 
 }  // namespace cbm::algo::trd2d
 
-#endif /* ALGO_DETECTORS_TRD2D_READOUTCONFIG_H_ */
+CBM_YAML_EXTERN_DECL(cbm::algo::trd2d::ReadoutConfig);
diff --git a/algo/detectors/trd2d/UnpackMS.h b/algo/detectors/trd2d/UnpackMS.h
index 7f1f4f53567392f295fb3b35f6625ece934a9047..264b30ae44fd398c9c6ba72141a2ab286c14dc91 100644
--- a/algo/detectors/trd2d/UnpackMS.h
+++ b/algo/detectors/trd2d/UnpackMS.h
@@ -6,10 +6,8 @@
 #include "CbmTrdDigi.h"
 #include "CbmTrdRawMessageSpadic.h"
 #include "MicrosliceDescriptor.hpp"
-#include "Timeslice.hpp"
 
 #include <array>
-#include <cmath>
 #include <memory>
 #include <sstream>
 
diff --git a/algo/global/Reco.cxx b/algo/global/Reco.cxx
index 785f6b936fef9da19ac79448fbb9cd637ac40fa1..57964a6958ffd3da413d8cfe3c90af7d495bcdd9 100644
--- a/algo/global/Reco.cxx
+++ b/algo/global/Reco.cxx
@@ -5,12 +5,22 @@
 
 #include "BuildInfo.h"
 #include "CbmDigiEvent.h"
+#include "EventbuildChain.h"
 #include "Exceptions.h"
+#include "HistogramSender.h"
+#include "bmon/Unpack.h"
+#include "ca/TrackingChain.h"
 #include "compat/OpenMP.h"
 #include "config/Yaml.h"
 #include "evbuild/Config.h"
 #include "log.hpp"
+#include "much/Unpack.h"
+#include "rich/Unpack.h"
 #include "sts/ChannelMaskSet.h"
+#include "sts/Unpack.h"
+#include "tof/Unpack.h"
+#include "trd/Unpack.h"
+#include "trd2d/Unpack.h"
 #include "util/TimingsFormat.h"
 #include "util/TsUtils.h"
 
@@ -80,9 +90,7 @@ void Reco::Init(const Options& opts)
   }
 
   // Reco Params
-  fs::path recoParamsPath = opts.ParamsDir() / "RecoParams.yaml";
-  YAML::Node yaml         = YAML::LoadFile(recoParamsPath.string());
-  fContext.recoParams     = config::Read<RecoParams>(yaml);
+  fContext.recoParams = config::ReadFromFile<RecoParams>(opts.ParamsDir() / "RecoParams.yaml");
 
   // Unpackers
   if (Opts().Has(Subsystem::BMON) && Opts().Has(Step::Unpack)) {
@@ -115,14 +123,12 @@ void Reco::Init(const Options& opts)
   }
 
   if (Opts().Has(Subsystem::TRD) && Opts().Has(Step::Unpack)) {
-    yaml       = YAML::LoadFile((Opts().ParamsDir() / "TrdReadoutSetup.yaml").string());
-    auto cfg   = config::Read<trd::ReadoutConfig>(yaml);
+    auto cfg   = config::ReadFromFile<trd::ReadoutConfig>(Opts().ParamsDir() / "TrdReadoutSetup.yaml");
     fTrdUnpack = std::make_unique<trd::Unpack>(cfg);
   }
 
   if (Opts().Has(Subsystem::TRD2D) && Opts().Has(Step::Unpack)) {
-    yaml         = YAML::LoadFile((Opts().ParamsDir() / "Trd2dReadoutSetup.yaml").string());
-    auto cfg     = config::Read<trd2d::ReadoutConfig>(yaml);
+    auto cfg     = config::ReadFromFile<trd2d::ReadoutConfig>(Opts().ParamsDir() / "Trd2dReadoutSetup.yaml");
     fTrd2dUnpack = std::make_unique<trd2d::Unpack>(cfg);
   }
 
@@ -132,9 +138,7 @@ void Reco::Init(const Options& opts)
   fEventBuild = std::make_unique<evbuild::EventbuildChain>(config, fSender);
 
   // STS Hitfinder
-  fs::path stsHitfinderParamsPath   = opts.ParamsDir() / "StsHitfinder.yaml";
-  yaml                              = YAML::LoadFile(stsHitfinderParamsPath.string());
-  sts::HitfinderPars hitFinderSetup = config::Read<sts::HitfinderPars>(yaml);
+  sts::HitfinderPars hitFinderSetup = config::ReadFromFile<sts::HitfinderPars>(opts.ParamsDir() / "StsHitfinder.yaml");
   hitFinderSetup.landauTable        = sts::LandauTable::FromFile(opts.ParamsDir() / "LandauWidthTable.txt");
   sts::HitfinderChainPars hitFinderPars;
   hitFinderPars.setup  = std::move(hitFinderSetup);
diff --git a/algo/global/Reco.h b/algo/global/Reco.h
index 569c7bbe8e17d511a2c3ffcdfcf6b2a6727f3cc4..6846544a888e080c1812cecf6e55ffe70474fa7b 100644
--- a/algo/global/Reco.h
+++ b/algo/global/Reco.h
@@ -1,37 +1,86 @@
 /* Copyright (C) 2023 FIAS Frankfurt Institute for Advanced Studies, Frankfurt / Main
    SPDX-License-Identifier: GPL-3.0-only
    Authors: Felix Weiglhofer [committer] */
-#ifndef CBM_ALGO_GLOBAL_RECO_H
-#define CBM_ALGO_GLOBAL_RECO_H
+#pragma once
 
 #include "AlgoTraits.h"
-#include "EventbuildChain.h"
-#include "HistogramSender.h"
 #include "SubChain.h"
-#include "bmon/Unpack.h"
-#include "ca/TrackingChain.h"
 #include "global/RecoResults.h"
-#include "much/Unpack.h"
-#include "rich/Unpack.h"
 #include "sts/HitfinderChain.h"
-#include "sts/Unpack.h"
 #include "tof/CalibratorChain.h"
 #include "tof/HitfinderChain.h"
-#include "tof/Unpack.h"
-#include "trd/Unpack.h"
-#include "trd2d/Unpack.h"
 
 #include <xpu/host.h>
 
+// fwd declarations
 namespace fles
 {
   class Timeslice;
-}  // namespace fles
+}
 
 namespace cbm::algo
 {
+  class HistogramSender;
   class Options;
+  class TrackingChain;
+
+  template<class M>
+  struct UnpackMonitor;
+
+  namespace bmon
+  {
+    class Unpack;
+  }
+
+  namespace much
+  {
+    class Unpack;
+  }
+
+  namespace rich
+  {
+    class Unpack;
+  }
+
+  namespace sts
+  {
+    class Unpack;
+  }
+
+  namespace tof
+  {
+    class Unpack;
+  }
+
+  namespace trd
+  {
+    class Unpack;
+  }
+
+  namespace trd2d
+  {
+    class Unpack;
+  }
+
+  namespace evbuild
+  {
+    class EventbuildChain;
+    struct EventbuildChainMonitorData;
+  }  // namespace evbuild
+
+  namespace ca
+  {
+    template<class C, class T>
+    class MonitorData;
+    enum class ECounter;
+    enum class ETimer;
+    using TrackingMonitorData = MonitorData<ECounter, ETimer>;
+  }  // namespace ca
 
+}  // namespace cbm::algo
+
+namespace cbm::algo
+{
   struct ProcessingMonitor {
     xpu::timings time;           //< total processing time
     xpu::timings timeUnpack;     //< time spent in unpacking
@@ -106,5 +155,3 @@ namespace cbm::algo
     void QueueProcessingMetrics(const ProcessingMonitor&);
   };
 }  // namespace cbm::algo
-
-#endif
diff --git a/algo/global/RecoResults.h b/algo/global/RecoResults.h
index 1fd92e64ca38a83e484338d3ac8b91b0a72e9912..4fa01c8f169b3cae67fe449d451f38f47ed3e15d 100644
--- a/algo/global/RecoResults.h
+++ b/algo/global/RecoResults.h
@@ -12,6 +12,7 @@
 #include "DigiData.h"
 #include "PartitionedSpan.h"
 #include "PartitionedVector.h"
+#include "ca/core/data/CaTrack.h"
 #include "ca/core/utils/CaVector.h"
 #include "sts/Cluster.h"
 #include "sts/Hit.h"
diff --git a/algo/global/RecoResultsInputArchive.cxx b/algo/global/RecoResultsInputArchive.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..650f014e8a222a3ee0656712e3a987211d3c700d
--- /dev/null
+++ b/algo/global/RecoResultsInputArchive.cxx
@@ -0,0 +1,11 @@
+/* Copyright (C) 2024 FIAS Frankfurt Institute for Advanced Studies, Frankfurt / Main
+   SPDX-License-Identifier: GPL-3.0-only
+   Authors: Felix Weiglhofer [committer] */
+
+#include "RecoResultsInputArchive.h"
+
+namespace fles
+{
+  template class InputArchive<cbm::algo::StorableRecoResults, cbm::algo::StorableRecoResults,
+                              ArchiveType::RecoResultsArchive>;
+}
diff --git a/algo/global/RecoResultsInputArchive.h b/algo/global/RecoResultsInputArchive.h
index 4291d47f573b5e57135b45aeeb3cdbada8424863..f73e338265f119354f78f69151dd6efb6c6acaa3 100644
--- a/algo/global/RecoResultsInputArchive.h
+++ b/algo/global/RecoResultsInputArchive.h
@@ -1,8 +1,7 @@
 /* Copyright (C) 2023 FIAS Frankfurt Institute for Advanced Studies, Frankfurt / Main
    SPDX-License-Identifier: GPL-3.0-only
    Authors: Felix Weiglhofer [committer] */
-#ifndef CBM_ALGO_GLOBAL_RECORESULTSINPUTARCHIVE_H
-#define CBM_ALGO_GLOBAL_RECORESULTSINPUTARCHIVE_H
+#pragma once
 
 #include "StorableRecoResults.h"
 
@@ -16,4 +15,9 @@ namespace cbm::algo
 
 }  // namespace cbm::algo
 
-#endif  // CBM_ALGO_GLOBAL_RECORESULTSINPUTARCHIVE_H
+// explicit instantiation of the template class because of long compile times
+namespace fles
+{
+  extern template class InputArchive<cbm::algo::StorableRecoResults, cbm::algo::StorableRecoResults,
+                                     ArchiveType::RecoResultsArchive>;
+}
diff --git a/algo/global/RecoResultsOutputArchive.cxx b/algo/global/RecoResultsOutputArchive.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..e1094f362b442c3a0f3c94c55f5f6e7d42c7a8e5
--- /dev/null
+++ b/algo/global/RecoResultsOutputArchive.cxx
@@ -0,0 +1,11 @@
+/* Copyright (C) 2024 FIAS Frankfurt Institute for Advanced Studies, Frankfurt / Main
+   SPDX-License-Identifier: GPL-3.0-only
+   Authors: Felix Weiglhofer [committer] */
+
+#include "RecoResultsOutputArchive.h"
+
+namespace fles
+{
+  template class OutputArchive<cbm::algo::StorableRecoResults, cbm::algo::StorableRecoResults,
+                               ArchiveType::RecoResultsArchive>;
+}
diff --git a/algo/global/RecoResultsOutputArchive.h b/algo/global/RecoResultsOutputArchive.h
index 2b574b51a8535ec3f868c3df2daf6fd217b2d539..8c673eb16df0676465c20f89e147555246c48a11 100644
--- a/algo/global/RecoResultsOutputArchive.h
+++ b/algo/global/RecoResultsOutputArchive.h
@@ -1,8 +1,7 @@
 /* Copyright (C) 2023 FIAS Frankfurt Institute for Advanced Studies, Frankfurt / Main
    SPDX-License-Identifier: GPL-3.0-only
    Authors: Felix Weiglhofer [committer] */
-#ifndef CBM_ALGO_GLOBAL_RECO_RESULTS_OUTPUT_ARCHIVE_H
-#define CBM_ALGO_GLOBAL_RECO_RESULTS_OUTPUT_ARCHIVE_H
+#pragma once
 
 #include "StorableRecoResults.h"
 
@@ -16,4 +15,9 @@ namespace cbm::algo
 
 }  // namespace cbm::algo
 
-#endif  // CBM_ALGO_GLOBAL_RECO_RESULTS_OUTPUT_ARCHIVE_H
+// explicit instantiation of the template class because of long compile times
+namespace fles
+{
+  extern template class OutputArchive<cbm::algo::StorableRecoResults, cbm::algo::StorableRecoResults,
+                                      ArchiveType::RecoResultsArchive>;
+}
diff --git a/core/data/trd/CbmTrdDigi.h b/core/data/trd/CbmTrdDigi.h
index 3124b5cf9bca726a58d35c4698c75e6eb9ece0cf..c8a5fcd2801c9fcf5f26421bac3a34822cad301b 100644
--- a/core/data/trd/CbmTrdDigi.h
+++ b/core/data/trd/CbmTrdDigi.h
@@ -12,7 +12,6 @@
 #endif
 
 #include <boost/serialization/access.hpp>
-#include <boost/serialization/base_object.hpp>
 
 #include <cstdint>
 #include <string>  // for string
diff --git a/core/data/trd/CbmTrdRawMessageSpadic.h b/core/data/trd/CbmTrdRawMessageSpadic.h
index abf4698f252a9ca102b65cfc7a2b1e7af637d605..dff22a0ea0cb70a7c890aa6bf8d0d7eb3b97f5db 100644
--- a/core/data/trd/CbmTrdRawMessageSpadic.h
+++ b/core/data/trd/CbmTrdRawMessageSpadic.h
@@ -12,7 +12,6 @@
 #define CbmTrdRawMessageSpadic_H
 
 #include <boost/serialization/access.hpp>
-#include <boost/serialization/base_object.hpp>
 #include <boost/serialization/vector.hpp>
 
 #include <cstdint>