diff --git a/src/mesh/Synchronizer.hpp b/src/mesh/Synchronizer.hpp
index dc0773ace208cc83e863df0ffada54e1db33f936..fcf5cc740d898ee9f5ec2cc5648205a1f8339c14 100644
--- a/src/mesh/Synchronizer.hpp
+++ b/src/mesh/Synchronizer.hpp
@@ -11,25 +11,27 @@
 
 #include <iostream>
 #include <map>
+#include <memory>
 
 #ifdef PUGS_HAS_MPI
 
 class Synchronizer
 {
+ private:
   template <ItemType item_type>
   using ExchangeItemTypeInfo = std::vector<Array<const ItemIdT<item_type>>>;
 
-  ExchangeItemTypeInfo<ItemType::cell> m_requested_cell_info;
-  ExchangeItemTypeInfo<ItemType::cell> m_provided_cell_info;
+  std::unique_ptr<ExchangeItemTypeInfo<ItemType::cell>> m_requested_cell_info;
+  std::unique_ptr<ExchangeItemTypeInfo<ItemType::cell>> m_provided_cell_info;
 
-  ExchangeItemTypeInfo<ItemType::face> m_requested_face_info;
-  ExchangeItemTypeInfo<ItemType::face> m_provided_face_info;
+  std::unique_ptr<ExchangeItemTypeInfo<ItemType::face>> m_requested_face_info;
+  std::unique_ptr<ExchangeItemTypeInfo<ItemType::face>> m_provided_face_info;
 
-  ExchangeItemTypeInfo<ItemType::edge> m_requested_edge_info;
-  ExchangeItemTypeInfo<ItemType::edge> m_provided_edge_info;
+  std::unique_ptr<ExchangeItemTypeInfo<ItemType::edge>> m_requested_edge_info;
+  std::unique_ptr<ExchangeItemTypeInfo<ItemType::edge>> m_provided_edge_info;
 
-  ExchangeItemTypeInfo<ItemType::node> m_requested_node_info;
-  ExchangeItemTypeInfo<ItemType::node> m_provided_node_info;
+  std::unique_ptr<ExchangeItemTypeInfo<ItemType::node>> m_requested_node_info;
+  std::unique_ptr<ExchangeItemTypeInfo<ItemType::node>> m_provided_node_info;
 
   template <ItemType item_type>
   PUGS_INLINE constexpr auto&
@@ -68,22 +70,24 @@ class Synchronizer
     const auto& item_owner = connectivity.template owner<item_type>();
     using ItemId           = ItemIdT<item_type>;
 
-    auto& requested_item_info = this->_getRequestedItemInfo<item_type>();
-    requested_item_info       = [&]() {
+    auto& p_requested_item_info = this->_getRequestedItemInfo<item_type>();
+    p_requested_item_info       = [&]() {
       std::vector<std::vector<ItemId>> requested_item_vector_info(parallel::size());
       for (ItemId item_id = 0; item_id < item_owner.numberOfItems(); ++item_id) {
         if (const size_t owner = item_owner[item_id]; owner != parallel::rank()) {
           requested_item_vector_info[owner].emplace_back(item_id);
         }
       }
-      std::vector<Array<const ItemId>> requested_item_info(parallel::size());
+      ExchangeItemTypeInfo<item_type> requested_item_info(parallel::size());
       for (size_t i_rank = 0; i_rank < parallel::size(); ++i_rank) {
         const auto& requested_item_vector = requested_item_vector_info[i_rank];
         requested_item_info[i_rank]       = convert_to_array(requested_item_vector);
       }
-      return requested_item_info;
+      return std::make_unique<ExchangeItemTypeInfo<item_type>>(std::move(requested_item_info));
     }();
 
+    auto& requested_item_info = *p_requested_item_info;
+
     Array<unsigned int> local_number_of_requested_values(parallel::size());
     for (size_t i_rank = 0; i_rank < parallel::size(); ++i_rank) {
       local_number_of_requested_values[i_rank] = requested_item_info[i_rank].size();
@@ -114,9 +118,9 @@ class Synchronizer
       item_number_to_id_correspondance[item_number[item_id]] = item_id;
     }
 
-    auto& provided_item_info = this->_getProvidedItemInfo<item_type>();
-    provided_item_info       = [&]() {
-      std::vector<Array<const ItemId>> provided_item_info(parallel::size());
+    auto& p_provided_item_info = this->_getProvidedItemInfo<item_type>();
+    p_provided_item_info       = [&]() {
+      ExchangeItemTypeInfo<item_type> provided_item_info(parallel::size());
       for (size_t i_rank = 0; i_rank < parallel::size(); ++i_rank) {
         Array<ItemId> provided_item_id_to_rank{local_number_of_values_to_send[i_rank]};
         const Array<int>& provided_item_number_to_rank = provided_item_number_list_by_rank[i_rank];
@@ -125,7 +129,7 @@ class Synchronizer
         }
         provided_item_info[i_rank] = provided_item_id_to_rank;
       }
-      return provided_item_info;
+      return std::make_unique<ExchangeItemTypeInfo<item_type>>(provided_item_info);
     }();
   }
 
@@ -137,15 +141,20 @@ class Synchronizer
 
     using ItemId = ItemIdT<item_type>;
 
-    const auto& provided_item_info  = this->_getProvidedItemInfo<item_type>();
-    const auto& requested_item_info = this->_getRequestedItemInfo<item_type>();
+    const auto& p_provided_item_info  = this->_getProvidedItemInfo<item_type>();
+    const auto& p_requested_item_info = this->_getRequestedItemInfo<item_type>();
 
-    Assert(requested_item_info.size() == provided_item_info.size());
+    Assert(static_cast<bool>(p_provided_item_info) == static_cast<bool>(p_requested_item_info));
 
-    if (provided_item_info.size() == 0) {
+    if (not p_provided_item_info) {
       this->_buildSynchronizeInfo<ConnectivityType, item_type>(connectivity);
     }
 
+    const auto& provided_item_info  = *p_provided_item_info;
+    const auto& requested_item_info = *p_requested_item_info;
+
+    Assert(requested_item_info.size() == provided_item_info.size());
+
     std::vector<Array<const DataType>> provided_data_list(parallel::size());
     for (size_t i_rank = 0; i_rank < parallel::size(); ++i_rank) {
       const Array<const ItemId>& provided_item_info_to_rank = provided_item_info[i_rank];
@@ -181,15 +190,20 @@ class Synchronizer
 
     using ItemId = ItemIdT<item_type>;
 
-    const auto& provided_item_info  = this->_getProvidedItemInfo<item_type>();
-    const auto& requested_item_info = this->_getRequestedItemInfo<item_type>();
+    const auto& p_provided_item_info  = this->_getProvidedItemInfo<item_type>();
+    const auto& p_requested_item_info = this->_getRequestedItemInfo<item_type>();
 
-    Assert(requested_item_info.size() == provided_item_info.size());
+    Assert(static_cast<bool>(p_provided_item_info) == static_cast<bool>(p_requested_item_info));
 
-    if (provided_item_info.size() == 0) {
+    if (not p_provided_item_info) {
       this->_buildSynchronizeInfo<ConnectivityType, item_type>(connectivity);
     }
 
+    const auto& provided_item_info  = *p_provided_item_info;
+    const auto& requested_item_info = *p_requested_item_info;
+
+    Assert(requested_item_info.size() == provided_item_info.size());
+
     const size_t size_of_arrays = item_array.sizeOfArrays();
 
     std::vector<Array<const DataType>> provided_data_list(parallel::size());
@@ -286,6 +300,12 @@ class Synchronizer
     }
   }
 
+  Synchronizer(const Synchronizer&) = delete;
+  Synchronizer(Synchronizer&&)      = delete;
+
+ private:
+  friend class SynchronizerManager;
+
   PUGS_INLINE
   Synchronizer()
   {
@@ -308,6 +328,12 @@ class Synchronizer
   synchronize(ItemArray<DataType, item_type, ConnectivityPtr>&)
   {}
 
+  Synchronizer(const Synchronizer&) = delete;
+  Synchronizer(Synchronizer&&)      = delete;
+
+ private:
+  friend class SynchronizerManager;
+
   PUGS_INLINE
   Synchronizer()
   {
diff --git a/src/mesh/SynchronizerManager.cpp b/src/mesh/SynchronizerManager.cpp
index a72191fd3bfc001c38e577384115bffaa441633c..45f2d17a4630a5268f8e7ba48cda9605235e0db7 100644
--- a/src/mesh/SynchronizerManager.cpp
+++ b/src/mesh/SynchronizerManager.cpp
@@ -45,7 +45,7 @@ SynchronizerManager::getConnectivitySynchronizer(const IConnectivity* connectivi
       connectivity_synchronizer != m_connectivity_synchronizer_map.end()) {
     return (*connectivity_synchronizer->second);
   } else {
-    std::shared_ptr synchronizer                  = std::make_shared<Synchronizer>();
+    std::shared_ptr<Synchronizer> synchronizer(new Synchronizer);
     m_connectivity_synchronizer_map[connectivity] = synchronizer;
     return *synchronizer;
   }
diff --git a/tests/test_Synchronizer.cpp b/tests/test_Synchronizer.cpp
index 6a4a9b52a6ce05a4a0b2758c868a49dc758d3e3d..8cc0ea66115d26271be227771547442864ada459 100644
--- a/tests/test_Synchronizer.cpp
+++ b/tests/test_Synchronizer.cpp
@@ -5,6 +5,7 @@
 #include <mesh/Connectivity.hpp>
 #include <mesh/Mesh.hpp>
 #include <mesh/Synchronizer.hpp>
+#include <mesh/SynchronizerManager.hpp>
 #include <utils/pugs_config.hpp>
 
 // clazy:excludeall=non-pod-global-static
@@ -57,7 +58,7 @@ TEST_CASE("Synchronizer", "[mesh]")
         REQUIRE(not is_same_item_value(node_value, node_value_ref));
       }
 
-      Synchronizer synchronizer;
+      Synchronizer& synchronizer = SynchronizerManager::instance().getConnectivitySynchronizer(&connectivity);
       synchronizer.synchronize(node_value);
 
       REQUIRE(is_same_item_value(node_value, node_value_ref));
@@ -82,7 +83,7 @@ TEST_CASE("Synchronizer", "[mesh]")
         REQUIRE(not is_same_item_value(edge_value, edge_value_ref));
       }
 
-      Synchronizer synchronizer;
+      Synchronizer& synchronizer = SynchronizerManager::instance().getConnectivitySynchronizer(&connectivity);
       synchronizer.synchronize(edge_value);
 
       REQUIRE(is_same_item_value(edge_value, edge_value_ref));
@@ -107,7 +108,7 @@ TEST_CASE("Synchronizer", "[mesh]")
         REQUIRE(not is_same_item_value(face_value, face_value_ref));
       }
 
-      Synchronizer synchronizer;
+      Synchronizer& synchronizer = SynchronizerManager::instance().getConnectivitySynchronizer(&connectivity);
       synchronizer.synchronize(face_value);
 
       REQUIRE(is_same_item_value(face_value, face_value_ref));
@@ -132,7 +133,7 @@ TEST_CASE("Synchronizer", "[mesh]")
         REQUIRE(not is_same_item_value(cell_value, cell_value_ref));
       }
 
-      Synchronizer synchronizer;
+      Synchronizer& synchronizer = SynchronizerManager::instance().getConnectivitySynchronizer(&connectivity);
       synchronizer.synchronize(cell_value);
 
       REQUIRE(is_same_item_value(cell_value, cell_value_ref));
@@ -163,7 +164,7 @@ TEST_CASE("Synchronizer", "[mesh]")
         REQUIRE(not is_same_item_array(cell_array, cell_array_ref));
       }
 
-      Synchronizer synchronizer;
+      Synchronizer& synchronizer = SynchronizerManager::instance().getConnectivitySynchronizer(&connectivity);
       synchronizer.synchronize(cell_array);
 
       REQUIRE(is_same_item_array(cell_array, cell_array_ref));
@@ -196,7 +197,7 @@ TEST_CASE("Synchronizer", "[mesh]")
         REQUIRE(not is_same_item_value(node_value, node_value_ref));
       }
 
-      Synchronizer synchronizer;
+      Synchronizer& synchronizer = SynchronizerManager::instance().getConnectivitySynchronizer(&connectivity);
       synchronizer.synchronize(node_value);
 
       REQUIRE(is_same_item_value(node_value, node_value_ref));
@@ -221,7 +222,7 @@ TEST_CASE("Synchronizer", "[mesh]")
         REQUIRE(not is_same_item_value(edge_value, edge_value_ref));
       }
 
-      Synchronizer synchronizer;
+      Synchronizer& synchronizer = SynchronizerManager::instance().getConnectivitySynchronizer(&connectivity);
       synchronizer.synchronize(edge_value);
 
       REQUIRE(is_same_item_value(edge_value, edge_value_ref));
@@ -246,7 +247,7 @@ TEST_CASE("Synchronizer", "[mesh]")
         REQUIRE(not is_same_item_value(face_value, face_value_ref));
       }
 
-      Synchronizer synchronizer;
+      Synchronizer& synchronizer = SynchronizerManager::instance().getConnectivitySynchronizer(&connectivity);
       synchronizer.synchronize(face_value);
 
       REQUIRE(is_same_item_value(face_value, face_value_ref));
@@ -271,7 +272,7 @@ TEST_CASE("Synchronizer", "[mesh]")
         REQUIRE(not is_same_item_value(cell_value, cell_value_ref));
       }
 
-      Synchronizer synchronizer;
+      Synchronizer& synchronizer = SynchronizerManager::instance().getConnectivitySynchronizer(&connectivity);
       synchronizer.synchronize(cell_value);
 
       REQUIRE(is_same_item_value(cell_value, cell_value_ref));
@@ -302,7 +303,7 @@ TEST_CASE("Synchronizer", "[mesh]")
         REQUIRE(not is_same_item_array(cell_array, cell_array_ref));
       }
 
-      Synchronizer synchronizer;
+      Synchronizer& synchronizer = SynchronizerManager::instance().getConnectivitySynchronizer(&connectivity);
       synchronizer.synchronize(cell_array);
 
       REQUIRE(is_same_item_array(cell_array, cell_array_ref));
@@ -335,7 +336,7 @@ TEST_CASE("Synchronizer", "[mesh]")
         REQUIRE(not is_same_item_value(node_value, node_value_ref));
       }
 
-      Synchronizer synchronizer;
+      Synchronizer& synchronizer = SynchronizerManager::instance().getConnectivitySynchronizer(&connectivity);
       synchronizer.synchronize(node_value);
 
       REQUIRE(is_same_item_value(node_value, node_value_ref));
@@ -360,7 +361,7 @@ TEST_CASE("Synchronizer", "[mesh]")
         REQUIRE(not is_same_item_value(edge_value, edge_value_ref));
       }
 
-      Synchronizer synchronizer;
+      Synchronizer& synchronizer = SynchronizerManager::instance().getConnectivitySynchronizer(&connectivity);
       synchronizer.synchronize(edge_value);
 
       REQUIRE(is_same_item_value(edge_value, edge_value_ref));
@@ -385,7 +386,7 @@ TEST_CASE("Synchronizer", "[mesh]")
         REQUIRE(not is_same_item_value(face_value, face_value_ref));
       }
 
-      Synchronizer synchronizer;
+      Synchronizer& synchronizer = SynchronizerManager::instance().getConnectivitySynchronizer(&connectivity);
       synchronizer.synchronize(face_value);
 
       REQUIRE(is_same_item_value(face_value, face_value_ref));
@@ -410,7 +411,7 @@ TEST_CASE("Synchronizer", "[mesh]")
         REQUIRE(not is_same_item_value(cell_value, cell_value_ref));
       }
 
-      Synchronizer synchronizer;
+      Synchronizer& synchronizer = SynchronizerManager::instance().getConnectivitySynchronizer(&connectivity);
       synchronizer.synchronize(cell_value);
 
       REQUIRE(is_same_item_value(cell_value, cell_value_ref));
@@ -441,7 +442,7 @@ TEST_CASE("Synchronizer", "[mesh]")
         REQUIRE(not is_same_item_array(cell_array, cell_array_ref));
       }
 
-      Synchronizer synchronizer;
+      Synchronizer& synchronizer = SynchronizerManager::instance().getConnectivitySynchronizer(&connectivity);
       synchronizer.synchronize(cell_array);
 
       REQUIRE(is_same_item_array(cell_array, cell_array_ref));