diff --git a/algo/ca/core/CMakeLists.txt b/algo/ca/core/CMakeLists.txt
index d527c55fcf7b535eeac15ed88fb38d1e54971d37..78756d5be14edbead64bf53208b1af5c71f2d082 100644
--- a/algo/ca/core/CMakeLists.txt
+++ b/algo/ca/core/CMakeLists.txt
@@ -26,6 +26,7 @@ set(SRCS
   ${CMAKE_CURRENT_SOURCE_DIR}/pars/CaSearchWindow.cxx
   ${CMAKE_CURRENT_SOURCE_DIR}/pars/CaStation.cxx
   ${CMAKE_CURRENT_SOURCE_DIR}/pars/CaStationInitializer.cxx
+  ${CMAKE_CURRENT_SOURCE_DIR}/utils/CaTimer.cxx
   ${CMAKE_CURRENT_SOURCE_DIR}/tracking/CaTrackFit.cxx
 )
 
@@ -87,6 +88,7 @@ install(
     utils/CaSimd.h
     utils/CaSimdVc.h
     utils/CaSimdPseudo.h
+    utils/CaTimer.h
     utils/CaVector.h
     utils/CaUtils.h
     utils/CaDefines.h
diff --git a/algo/ca/core/utils/CaMonitor.h b/algo/ca/core/utils/CaMonitor.h
index 5ba1711a4071a8375ca6b12d0ae1b5e0a51ce16e..749f11fc826f1320713742d2dd03d86ac7de726f 100644
--- a/algo/ca/core/utils/CaMonitor.h
+++ b/algo/ca/core/utils/CaMonitor.h
@@ -2,66 +2,66 @@
    SPDX-License-Identifier: GPL-3.0-only
    Authors: Sergei Zharko [committer] */
 
-/// @file   CaMonitor.h
-/// @brief  CA Tracking monitor class
-/// @since  25.08.2023
-/// @author S.Zharko <s.zharko@gsi.de>
+/// \file   CaMonitor.h
+/// \brief  CA Tracking monitor class
+/// \since  25.08.2023
+/// \author S.Zharko <s.zharko@gsi.de>
 
 #pragma once  // include this header only once per compilation unit
 
-
 #include <iomanip>
 #include <sstream>
 #include <string>
 
 #include "CaEnumArray.h"
+#include "CaTimer.h"
 
 namespace cbm::algo::ca
 {
-  /// @class  Monitor
-  /// @brief  Monitor class for CA tracking
-  /// @tparam EMonitorKey  A enum class, containing keys for monitorables
+  /// \class  Monitor
+  /// \brief  Monitor class for the CA tracking
+  /// \tparam EMonitorKey  A enum class, containing keys for monitorables
   ///
   template<class EMonitorKey>
   class Monitor {
   public:
-    /// @brief Alias to array, indexed by Monitorable enumeration
+    /// \brief Alias to array, indexed by Monitorable enumeration
     template<typename T>
     using MonitorableArr_t = EnumArray<EMonitorKey, T>;
 
-    /// @brief Constructor
-    /// @param name Name of monitor
+    /// \brief Constructor
+    /// \param name Name of monitor
     Monitor(const std::string& name) : fsName(name) {}
 
-    /// @brief Gets key name
-    /// @param key Monitorable key
+    /// \brief Gets key name
+    /// \param key Monitorable key
     const std::string& GetKeyName(EMonitorKey key) const { return faKeyNames[key]; }
 
-    /// @brief Gets counter value
-    /// @param key
+    /// \brief Gets counter value
+    /// \param key
     int GetValue(EMonitorKey key) const { return faKeyCounters[key]; }
 
-    /// @brief Increments key counter by 1
-    /// @param key Monitorable key
+    /// \brief Increments key counter by 1
+    /// \param key Monitorable key
     void Increment(EMonitorKey key) { ++faKeyCounters[key]; };
 
-    /// @brief Increments key counter by a number
-    /// @param key  Monitorable key
-    /// @param num  Number to add
+    /// \brief Increments key counter by a number
+    /// \param key  Monitorable key
+    /// \param num  Number to add
     void Increment(EMonitorKey key, int num) { faKeyCounters[key] += num; }
 
-    /// @brief Resets the counters
+    /// \brief Resets the counters
     void Reset() { faKeyCounters.fill(0); }
 
-    /// @brief Sets keys of monitorables, which are used as denominators for ratios
-    /// @param vKeys Vector of keys
+    /// \brief Sets keys of monitorables, which are used as denominators for ratios
+    /// \param vKeys Vector of keys
     void SetRatioKeys(const std::vector<EMonitorKey>& vKeys) { fvRatioKeys = vKeys; }
 
-    /// @brief Sets name of key
-    /// @param name  Name of monitoralble
+    /// \brief Sets name of key
+    /// \param name  Name of monitoralble
     void SetKeyName(EMonitorKey key, const char* name) { faKeyNames[key] = name; }
 
-    /// @brief Prints counters summary to string
+    /// \brief Prints counters summary to string
     std::string ToString() const;
 
   private:
@@ -71,11 +71,11 @@ namespace cbm::algo::ca
     MonitorableArr_t<int> faKeyCounters {};       ///< Counters of keys
   };
 
+
   // *****************************************
   // **  Template function implementations  **
   // *****************************************
 
-
   // ---------------------------------------------------------------------------------------------------------------------
   //
   template<class EMonitorKey>
diff --git a/algo/ca/core/utils/CaTimer.cxx b/algo/ca/core/utils/CaTimer.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..84cc02a6e41b403292f1d2f8e07260a85040b00d
--- /dev/null
+++ b/algo/ca/core/utils/CaTimer.cxx
@@ -0,0 +1,29 @@
+/* Copyright (C) 2023 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
+   SPDX-License-Identifier: GPL-3.0-only
+   Authors: Sergei Zharko [committer] */
+
+/// \file   CaTimer.h
+/// \brief  Timer class for CA tracking (implementation)
+/// \since  18.10.2023
+/// \author S.Zharko <s.zharko@gsi.de>
+
+#include "CaTimer.h"
+
+#include <iomanip>
+#include <sstream>
+
+using cbm::algo::ca::Timer;
+
+// ---------------------------------------------------------------------------------------------------------------------
+//
+std::string Timer::ToString() const
+{
+  using std::left;
+  using std::right;
+  using std::setw;
+
+  std::stringstream msg;
+  msg << left << setw(25) << fName << right << " min = " << setw(15) << fMin << " ns, max = " << setw(15) << fMax
+      << " ns, average = " << setw(15) << GetAverage() << " ns, total = " << fTotal << " ns, N calls = " << fNofCalls;
+  return msg.str();
+}
diff --git a/algo/ca/core/utils/CaTimer.h b/algo/ca/core/utils/CaTimer.h
new file mode 100644
index 0000000000000000000000000000000000000000..49f8be69e7411236645059d1ab85121c26018a79
--- /dev/null
+++ b/algo/ca/core/utils/CaTimer.h
@@ -0,0 +1,129 @@
+/* Copyright (C) 2023 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
+   SPDX-License-Identifier: GPL-3.0-only
+   Authors: Sergei Zharko [committer] */
+
+/// \file   CaTimer.h
+/// \brief  Timer class for CA tracking (header)
+/// \since  18.10.2023
+/// \author S.Zharko <s.zharko@gsi.de>
+
+#pragma once
+
+#include <chrono>
+#include <cstdint>
+#include <limits>
+#include <string>
+
+namespace cbm::algo::ca
+{
+  /// \class  Timer
+  /// \brief  A timer class for the monitor
+  ///
+  class Timer {
+  public:
+    using Clock         = std::chrono::high_resolution_clock;
+    using Duration      = std::chrono::nanoseconds;
+    using DurationCount = Duration::rep;
+    using TimePoint     = std::chrono::time_point<Clock, Duration>;
+
+    /// \brief Default constructor
+    Timer() = default;
+
+    /// \brief Destructor
+    ~Timer() = default;
+
+    /// \brief Copy constructor
+    Timer(const Timer&) = default;
+
+    /// \brief Move constructor
+    Timer(Timer&&) = default;
+
+    /// \brief Copy assignment operator
+    Timer& operator=(const Timer&) = default;
+
+    /// \brief Move assignment operator
+    Timer& operator=(Timer&&) = default;
+
+    /// \brief Gets average time [ns]
+    DurationCount GetAverage() const { return fTotal / fNofCalls; }
+
+    /// \brief Gets time of the longest call [ns]
+    DurationCount GetMax() const { return fMax; }
+
+    /// \brief Gets time of the shortest call [ns]
+    DurationCount GetMin() const { return fMin; }
+
+    /// \brief Gets index of the longest call
+    int GetMaxCallIndex() const { return fMaxCallIndex; }
+
+    /// \brief Gets index of the longest call
+    int GetMinCallIndex() const { return fMinCallIndex; }
+
+    /// \brief Gets name
+    const std::string& GetName() const { return fName; }
+
+    /// \brief Gets total time [ns]
+    DurationCount GetTotal() const;
+
+    /// \brief Resets the timer
+    void Reset();
+
+    /// \brief Sets name
+    void SetName(const std::string& name) { fName = name; }
+
+    /// \brief Starts the timer
+    void Start() { fStart = Clock::now(); }
+
+    /// \brief Stops the timer
+    void Stop();
+
+    /// \brief Prints statistics
+    std::string ToString() const;
+
+  private:
+    std::string fName    = "no name";  ///< Name of the timer
+    TimePoint fStart     = TimePoint();
+    DurationCount fMin   = std::numeric_limits<DurationCount>::max();  ///< Minimal time period
+    DurationCount fMax   = std::numeric_limits<DurationCount>::min();  ///< Maximal time period
+    DurationCount fTotal = DurationCount(0);                           ///< Total measured time period
+    int fNofCalls        = 0;                                          ///< Number of timer calls
+    int fMinCallIndex    = -1;                                         ///< Index of the shortest call
+    int fMaxCallIndex    = -1;                                         ///< Index of the longest call
+  };                                                                   // class Timer
+
+
+  // ************************************
+  // **   Inline function definition   **
+  // ************************************
+
+  // -------------------------------------------------------------------------------------------------------------------
+  //
+  inline void Timer::Reset()
+  {
+    fStart        = TimePoint();
+    fMin          = std::numeric_limits<DurationCount>::max();
+    fMax          = std::numeric_limits<DurationCount>::min();
+    fMinCallIndex = -1;
+    fMaxCallIndex = -1;
+    fTotal        = DurationCount(0);
+    fNofCalls     = 0;
+  }
+
+  // -------------------------------------------------------------------------------------------------------------------
+  //
+  inline void Timer::Stop()
+  {
+    auto stop = Clock::now();
+    auto time = std::chrono::duration_cast<Duration>(stop - fStart).count();
+    if (fMin > time) {
+      fMin          = time;
+      fMinCallIndex = fNofCalls;
+    }
+    else if (fMax < time) {
+      fMax          = time;
+      fMaxCallIndex = fNofCalls;
+    }
+    fTotal += time;
+    ++fNofCalls;
+  }
+}  // namespace cbm::algo::ca
\ No newline at end of file
diff --git a/reco/L1/CbmL1.cxx b/reco/L1/CbmL1.cxx
index f32cff1496a7c8269905801f604c861d1acc0a25..25a31f9f4c11765f111ba603da4e6d6ea879a957 100644
--- a/reco/L1/CbmL1.cxx
+++ b/reco/L1/CbmL1.cxx
@@ -796,7 +796,7 @@ void CbmL1::Reconstruct(CbmEvent* event)
   if (fVerbose > 1) { LOG(info) << "L1 Track finder..."; }
   fpAlgo->CaTrackFinder();
   //       IdealTrackFinder();
-  fTrackingTime = fpAlgo->fCaRecoTime;
+  fTrackingTime = fpAlgo->fCaRecoTime;  // TODO: remove (not used)
 
   if (fVerbose > 1) { LOG(info) << "L1 Track finder ok"; }
 
@@ -825,7 +825,8 @@ void CbmL1::Reconstruct(CbmEvent* event)
 
   fMonitor.Increment(EMonitorKey::kRecoTrack, fvRecoTracks.size());
 
-  LOG(debug) << "CA Track Finder: " << fpAlgo->fCaRecoTime << " s/sub-ts";
+  LOG(info) << "CA Track Finder: " << fpAlgo->fCaRecoTime << " s/sub-ts";
+  LOG(info) << GetName() << ": " << fpAlgo->fRecoTimer.ToString();
 
 
   // output performance
diff --git a/reco/L1/CbmL1.h b/reco/L1/CbmL1.h
index 239e692043a69985cb8419979c355137e487a8d2..f430443a2a4d4cda4884b3f744a62367e4f3ca35 100644
--- a/reco/L1/CbmL1.h
+++ b/reco/L1/CbmL1.h
@@ -539,6 +539,7 @@ private:
   Int_t fPerformance   = 0;   ///< performance mode: 0 - w\o perf. 1 - L1-Efficiency definition. 2 - QA-Eff.definition
   double fTrackingTime = 0.;  ///< time of track finding procedure
 
+
   /// Option to work with files for the standalone mode
   ///  - #0 standalone mode is not used
   ///  - #1 data for standalone mode is written to configuration file (currently does not work)
diff --git a/reco/L1/L1Algo/L1Algo.cxx b/reco/L1/L1Algo/L1Algo.cxx
index 82c52410de8aa337af0eaea0839af489bf9b7fb8..910afa8a7deb887df4eef2a1c4f404921c6c369f 100644
--- a/reco/L1/L1Algo/L1Algo.cxx
+++ b/reco/L1/L1Algo/L1Algo.cxx
@@ -53,6 +53,9 @@ void L1Algo::ReceiveParameters(Parameters&& parameters)
   fGhostSuppression = fParameters.GetGhostSuppression();
 
   ca::FieldRegion::ForceUseOfOriginalField(fParameters.DevIsUseOfOriginalField());
+
+  fRecoTimer.SetName("track finder + track fitter");
+  fRecoTimer.Reset();
 }
 
 int L1Algo::GetMcTrackIdForCaHit(int iHit) const
diff --git a/reco/L1/L1Algo/L1Algo.h b/reco/L1/L1Algo/L1Algo.h
index e625198f28e0704481fa293a012ad9198313094a..f33bae1a6cc77f8803eb7d55afd35122bed01e17 100644
--- a/reco/L1/L1Algo/L1Algo.h
+++ b/reco/L1/L1Algo/L1Algo.h
@@ -35,6 +35,7 @@ class L1AlgoDraw;
 #include "CaMeasurementXy.h"
 #include "CaParameters.h"
 #include "CaStation.h"
+#include "CaTimer.h"
 #include "CaTrack.h"
 #include "CaTrackParam.h"
 #include "CaTriplet.h"
@@ -45,13 +46,6 @@ using namespace cbm::algo::ca;  //TODO: remove
 
 class CbmL1MCTrack;
 
-//namespace
-//{
-//  using cbm::algo::ca::Track;      // TMP
-//  using cbm::algo::ca::Vector;     // TMP
-//  using cbm::algo::ca::Iteration;  // TMP
-//}  // namespace
-
 // *******************************
 // ** Types definition (global) **
 // *******************************
@@ -304,6 +298,8 @@ public:
 
   double fCaRecoTime {0.};  // time of the track finder + fitter
 
+  ca::Timer fRecoTimer;  // TMP
+
   Vector<Track> fRecoTracks {"L1Algo::fRecoTracks"};       ///< reconstructed tracks
   Vector<ca::HitIndex_t> fRecoHits {"L1Algo::fRecoHits"};  ///< packed hits of reconstructed tracks
 
diff --git a/reco/L1/L1Algo/L1CaTrackFinder.cxx b/reco/L1/L1Algo/L1CaTrackFinder.cxx
index ab026223b16dda9e10b5603808ef29770ec30292..081b193c94cabb067b495dbdfbdae8ca7939aec5 100644
--- a/reco/L1/L1Algo/L1CaTrackFinder.cxx
+++ b/reco/L1/L1Algo/L1CaTrackFinder.cxx
@@ -33,7 +33,9 @@ void L1Algo::CaTrackFinder()
   // and runs the track finder over the sub-slices
   //
 
+  fRecoTimer.Reset();
   auto timerStart = std::chrono::high_resolution_clock::now();
+  fRecoTimer.Start();
 
   // ----- Reset data arrays -------------------------------------------------------------------------------------------
   fvHitKeyFlags.reset(fInputData.GetNhitKeys(), 0);
@@ -227,6 +229,7 @@ void L1Algo::CaTrackFinder()
   }
 
   auto timerEnd = std::chrono::high_resolution_clock::now();
+  fRecoTimer.Stop();
   fCaRecoTime   = (double) (std::chrono::duration<double>(timerEnd - timerStart).count());
   LOG(debug) << "CaTracker: nSubSlices processed = " << nSubSlices;
 }