diff --git a/algo/global/Archive.cxx b/algo/global/Archive.cxx
index 6084543697fe69f33dce124dc78b9df3a27b25af..9a2c1fa69afba8158d63c502b7e8f5d33835cc9d 100644
--- a/algo/global/Archive.cxx
+++ b/algo/global/Archive.cxx
@@ -5,11 +5,14 @@
 
 #include "CbmStsDigi.h"
 
+#include <boost/algorithm/string.hpp>
 #include <boost/archive/binary_iarchive.hpp>
 #include <boost/archive/binary_oarchive.hpp>
 #include <boost/serialization/vector.hpp>
 
 #include <fstream>
+#include <iomanip>
+#include <sstream>
 
 #include "log.hpp"
 
@@ -25,10 +28,28 @@ Archive::Archive(fs::path file)
   ia >> *this;
 }
 
-void Archive::Store(fs::path file) const
+void Archive::Store(fs::path file, std::optional<size_t> tsId) const
 {
+  file = makeFileName(file, tsId);
+
   L_(info) << "Writing archive to " << file;
   std::ofstream ofs(file.string(), std::ios::binary);
   ba::binary_oarchive oa(ofs);
   oa << *this;
 }
+
+fs::path Archive::makeFileName(fs::path file, std::optional<size_t> tsId) const
+{
+  if (!tsId) return file;
+
+  // Shamelessly copied from fles::OutputArchiveSequence
+  if (file.string().find("%n") == std::string::npos) {
+    L_(warning)
+      << "Archive file name does not contain %n wildcard (timeslice number). Appending id to file name instead.";
+    file += "_%n";
+  }
+
+  std::ostringstream number;
+  number << std::setw(4) << std::setfill('0') << *tsId;
+  return boost::replace_all_copy(file.string(), "%n", number.str());
+}
diff --git a/algo/global/Archive.h b/algo/global/Archive.h
index 4f97dc3ac92ac2f42e32c56ea0586fa836761dc1..c3f05df94a3fb68492da3c3b448620d795da00be 100644
--- a/algo/global/Archive.h
+++ b/algo/global/Archive.h
@@ -9,6 +9,7 @@
 #include <boost/serialization/access.hpp>
 #include <boost/serialization/version.hpp>
 
+#include <optional>
 #include <vector>
 
 #include "RecoIO.h"
@@ -32,7 +33,7 @@ namespace cbm::algo
     /**
      * @brief Store Archive object to file.
     */
-    void Store(fs::path file) const;
+    void Store(fs::path file, std::optional<size_t> tsId = {}) const;
 
     const std::vector<fles::SubsystemIdentifier>& Detectors() const { return fDetectors; }
 
@@ -41,7 +42,6 @@ namespace cbm::algo
 
   private:
     std::vector<fles::SubsystemIdentifier> fDetectors;
-
     std::vector<RecoIO> fTimesliceResults;
 
     friend class boost::serialization::access;
@@ -51,6 +51,8 @@ namespace cbm::algo
       ar& fDetectors;
       ar& fTimesliceResults;
     }
+
+    fs::path makeFileName(fs::path file, std::optional<size_t> tsId) const;
   };
 }  // namespace cbm::algo
 
diff --git a/algo/global/Reco.h b/algo/global/Reco.h
index 276bc591fb546de7faeafb6aeddcc05a0413c760..3dd0e5cfb4cab3ce2e77cdf3bdcc8772f33e4085 100644
--- a/algo/global/Reco.h
+++ b/algo/global/Reco.h
@@ -25,10 +25,10 @@ namespace cbm::algo
     Reco();
     ~Reco();
 
-    Reco(const Reco&)            = delete;
+    Reco(const Reco&) = delete;
     Reco& operator=(const Reco&) = delete;
     Reco(Reco&&)                 = delete;
-    Reco& operator=(Reco&&)      = delete;
+    Reco& operator=(Reco&&) = delete;
 
     void Init(const Options&);
     RecoIO Run(const fles::Timeslice&);
diff --git a/reco/app/cbmreco/main.cxx b/reco/app/cbmreco/main.cxx
index dd694294c7aa508483f5583791c88482f1ebd6ff..1bfd1674a9f1724ddd7b9e634125fdc3b444a26d 100644
--- a/reco/app/cbmreco/main.cxx
+++ b/reco/app/cbmreco/main.cxx
@@ -58,19 +58,20 @@ int main(int argc, char** argv)
     }
     auto result = reco.Run(*ts);
 
-    if (opts.WritePerTimeslice() && !opts.OutputFile().empty()) {
+    if (opts.SplitOutputPerTS() && !opts.OutputFile().empty()) {
       Archive tsResults({fles::SubsystemIdentifier::STS});  // TODO: use opts.Detector() once detector flag is merged
-      tsResults.TimesliceResults().push_back(result);
-      // TODO: handle file endings
-      tsResults.Store(fmt::format("{}_{}", opts.OutputFile().string(), ts->index()));
+      tsResults.TimesliceResults().emplace_back(std::move(result));
+      tsResults.Store(opts.OutputFile(), ts->index());
+    }
+    else {
+      archive.TimesliceResults().emplace_back(std::move(result));
     }
-    archive.TimesliceResults().push_back(result);  // TODO: result should be moved not copied
     tsIdx++;
 
     if (num_ts > 0 && tsIdx >= num_ts) { break; }
   }
 
-  if (!opts.WritePerTimeslice() && !opts.OutputFile().empty()) archive.Store(opts.OutputFile());
+  if (!opts.SplitOutputPerTS() && !opts.OutputFile().empty()) archive.Store(opts.OutputFile());
   reco.Finalize();
 
   return 0;