diff --git a/src/main.cpp b/src/main.cpp
index 466806afb3a96bd5e6c28e5890327794d174fc52..fe8b4eb4842f174a3ee81a4b9809c6a98535c30d 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -22,6 +22,8 @@
 
 #include <GmshReader.hpp>
 
+#include <SynchronizerManager.hpp>
+
 #include <limits>
 #include <map>
 
@@ -30,6 +32,8 @@ int main(int argc, char *argv[])
   std::string filename = initialize(argc, argv);
   std::map<std::string, double> method_cost_map;
 
+  SynchronizerManager::create();
+
   if (filename != "") {
     pout() << "Reading (gmsh) " << rang::style::underline << filename << rang::style::reset << " ...\n";
     Timer gmsh_timer;
@@ -373,6 +377,8 @@ int main(int argc, char *argv[])
     std::exit(0);
   }
 
+  SynchronizerManager::destroy();
+
   finalize();
 
   std::string::size_type size=0;
diff --git a/src/mesh/CMakeLists.txt b/src/mesh/CMakeLists.txt
index e9f66aa5c35e8d1d877c91e5b9b701f38be8ef30..3569306a44f5fce39435bd24a457a25a6e660f8e 100644
--- a/src/mesh/CMakeLists.txt
+++ b/src/mesh/CMakeLists.txt
@@ -7,7 +7,8 @@ add_library(
   PastisMesh
   Connectivity.cpp
   ConnectivityComputer.cpp
-  GmshReader.cpp)
+  GmshReader.cpp
+  SynchronizerManager.cpp)
 
 include_directories(${PASTIS_BINARY_DIR}/src/utils)
 
diff --git a/src/mesh/Connectivity.hpp b/src/mesh/Connectivity.hpp
index bebb67e014cddf792cd4cd47f462024edb448f6e..e07a26a275e5765cb21c2f2a4549015865c927ce 100644
--- a/src/mesh/Connectivity.hpp
+++ b/src/mesh/Connectivity.hpp
@@ -31,6 +31,8 @@
 #include <RefNodeList.hpp>
 #include <RefFaceList.hpp>
 
+#include <SynchronizerManager.hpp>
+
 #include <tuple>
 #include <algorithm>
 #include <set>
@@ -635,7 +637,8 @@ class Connectivity final
  public:
   ~Connectivity()
   {
-    ;
+    auto& manager = SynchronizerManager::instance();
+    manager.deleteConnectivitySynchronizer(this);
   }
 };
 
diff --git a/src/mesh/ItemValueUtils.hpp b/src/mesh/ItemValueUtils.hpp
index d6f60ebcb74283119dee127540917bf4ebe9f109..6c45be4c283a69a729eb7d1cdda25480ba96d2d6 100644
--- a/src/mesh/ItemValueUtils.hpp
+++ b/src/mesh/ItemValueUtils.hpp
@@ -6,6 +6,7 @@
 
 #include <Connectivity.hpp>
 
+#include <SynchronizerManager.hpp>
 #include <Synchronizer.hpp>
 
 template <typename DataType,
@@ -300,7 +301,9 @@ void synchronize(ItemValue<DataType, item_type, ConnectivityPtr>& item_value)
 {
   static_assert(not std::is_const_v<DataType>, "cannot synchronize ItemValue of const data");
   if (parallel::size() > 1) {
-    static Synchronizer synchronizer;
+    auto& manager = SynchronizerManager::instance();
+    const IConnectivity* connectivity = item_value.connectivity_ptr().get();
+    Synchronizer& synchronizer = manager.getConnectivitySynchronizer(connectivity);
     synchronizer.synchronize(item_value);
   }
 }
diff --git a/src/mesh/Synchronizer.hpp b/src/mesh/Synchronizer.hpp
index 8f82e3a330b2d01b176e94cdde7a74334bc9d2c2..a44a17ed3738625d7cfbef3c30c1fb45a3d62621 100644
--- a/src/mesh/Synchronizer.hpp
+++ b/src/mesh/Synchronizer.hpp
@@ -61,8 +61,6 @@ class Synchronizer
     using ItemId = ItemIdT<item_type>;
 
     auto& requested_item_info = this->_getRequestedItemInfo<item_type>();
-
-    pout() << "... building synchronization info\n";
     requested_item_info
         = [&] () {
             std::vector<std::vector<ItemId>> requested_item_vector_info(parallel::size());
diff --git a/src/mesh/SynchronizerManager.cpp b/src/mesh/SynchronizerManager.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..1db720e396a40e0d15c952c5fefbbfd7f5b7597e
--- /dev/null
+++ b/src/mesh/SynchronizerManager.cpp
@@ -0,0 +1,53 @@
+#include <SynchronizerManager.hpp>
+#include <PastisAssert.hpp>
+
+#include <Messenger.hpp>
+#include <Synchronizer.hpp>
+
+SynchronizerManager*
+SynchronizerManager::m_instance{nullptr};
+
+SynchronizerManager::
+~SynchronizerManager()
+{
+  if (m_connectivity_synchronizer_map.size() > 0)
+  {
+    perr() << __FILE__ << ':' << __LINE__
+           << ": warning: some connectivities are still registered\n";;
+  }
+}
+
+void SynchronizerManager::create()
+{
+  Assert(m_instance == nullptr, "SynchronizerManager is already created");
+  m_instance = new SynchronizerManager;
+}
+
+void SynchronizerManager::destroy()
+{
+  Assert(m_instance != nullptr, "SynchronizerManager was not created!");
+  delete m_instance;
+  m_instance = nullptr;
+}
+
+
+void
+SynchronizerManager::
+deleteConnectivitySynchronizer(const IConnectivity* connectivity)
+{
+  m_connectivity_synchronizer_map.erase(connectivity);
+}
+
+Synchronizer&
+SynchronizerManager::
+getConnectivitySynchronizer(const IConnectivity* connectivity)
+{
+  if (auto connectivity_synchronizer = m_connectivity_synchronizer_map.find(connectivity);
+      connectivity_synchronizer != m_connectivity_synchronizer_map.end()) {
+    return (*connectivity_synchronizer->second);
+  } else {
+    std::shared_ptr synchronizer = std::make_shared<Synchronizer>();
+    m_connectivity_synchronizer_map[connectivity] = synchronizer;
+    return *synchronizer;
+  }
+}
diff --git a/src/mesh/SynchronizerManager.hpp b/src/mesh/SynchronizerManager.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..3fdf57d9b97cebb782a0c7c4ab1cbf5ec1fc4904
--- /dev/null
+++ b/src/mesh/SynchronizerManager.hpp
@@ -0,0 +1,37 @@
+#ifndef SYNCHRONIZER_MANAGER_HPP
+#define SYNCHRONIZER_MANAGER_HPP
+
+#include <PastisMacros.hpp>
+#include <PastisAssert.hpp>
+
+#include <memory>
+#include <map>
+
+class IConnectivity;
+class Synchronizer;
+
+class SynchronizerManager
+{
+ private:
+  std::map<const IConnectivity*, std::shared_ptr<Synchronizer>> m_connectivity_synchronizer_map;
+
+  static SynchronizerManager* m_instance;
+  SynchronizerManager() = default;
+  ~SynchronizerManager();
+
+ public:
+  static void create();
+  static void destroy();
+
+  PASTIS_INLINE
+  static SynchronizerManager& instance()
+  {
+    Assert(m_instance != nullptr, "SynchronizerManager was not created!");
+    return *m_instance;
+  }
+
+  void deleteConnectivitySynchronizer(const IConnectivity*);
+  Synchronizer& getConnectivitySynchronizer(const IConnectivity*);
+};
+
+#endif // SYNCHRONIZER_MANAGER_HPP