diff --git a/src/mesh/Synchronizer.hpp b/src/mesh/Synchronizer.hpp
index adf127f238fc201a11ba5b503aed4b926e772a4d..dc0773ace208cc83e863df0ffada54e1db33f936 100644
--- a/src/mesh/Synchronizer.hpp
+++ b/src/mesh/Synchronizer.hpp
@@ -7,9 +7,13 @@
 #include <utils/Exceptions.hpp>
 #include <utils/Messenger.hpp>
 
+#include <utils/pugs_config.hpp>
+
 #include <iostream>
 #include <map>
 
+#ifdef PUGS_HAS_MPI
+
 class Synchronizer
 {
   template <ItemType item_type>
@@ -289,4 +293,28 @@ class Synchronizer
   }
 };
 
+#else   // PUGS_HAS_MPI
+
+class Synchronizer
+{
+ public:
+  template <typename DataType, ItemType item_type, typename ConnectivityPtr>
+  PUGS_INLINE void
+  synchronize(ItemValue<DataType, item_type, ConnectivityPtr>&)
+  {}
+
+  template <typename DataType, ItemType item_type, typename ConnectivityPtr>
+  PUGS_INLINE void
+  synchronize(ItemArray<DataType, item_type, ConnectivityPtr>&)
+  {}
+
+  PUGS_INLINE
+  Synchronizer()
+  {
+    ;
+  }
+};
+
+#endif   // PUGS_HAS_MPI
+
 #endif   // SYNCHRONIZER_HPP
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index ea44f119d6096cbd1b304c39c00400eefec16ca2..ddfa977a6ef8ca76df9f27bbdc2bda86395cc67f 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -174,6 +174,7 @@ add_executable (mpi_unit_tests
   test_RandomEngine.cpp
   test_SubItemValuePerItem.cpp
   test_SubItemArrayPerItem.cpp
+  test_Synchronizer.cpp
   )
 
 add_library(test_Pugs_MeshDataBase
diff --git a/tests/test_Synchronizer.cpp b/tests/test_Synchronizer.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..6a4a9b52a6ce05a4a0b2758c868a49dc758d3e3d
--- /dev/null
+++ b/tests/test_Synchronizer.cpp
@@ -0,0 +1,450 @@
+#include <catch2/catch_test_macros.hpp>
+#include <catch2/matchers/catch_matchers_all.hpp>
+
+#include <MeshDataBaseForTests.hpp>
+#include <mesh/Connectivity.hpp>
+#include <mesh/Mesh.hpp>
+#include <mesh/Synchronizer.hpp>
+#include <utils/pugs_config.hpp>
+
+// clazy:excludeall=non-pod-global-static
+
+TEST_CASE("Synchronizer", "[mesh]")
+{
+  auto is_same_item_value = [](auto a, auto b) {
+    using IndexT = typename decltype(a)::index_type;
+    bool is_same = true;
+    for (IndexT i = 0; i < a.numberOfItems(); ++i) {
+      is_same &= (a[i] == b[i]);
+    }
+    return parallel::allReduceAnd(is_same);
+  };
+
+  auto is_same_item_array = [](auto a, auto b) {
+    using IndexT = typename decltype(a)::index_type;
+    bool is_same = true;
+    for (IndexT i = 0; i < a.numberOfItems(); ++i) {
+      for (size_t j = 0; j < a.sizeOfArrays(); ++j) {
+        is_same &= (a[i][j] == b[i][j]);
+      }
+    }
+    return parallel::allReduceAnd(is_same);
+  };
+
+  SECTION("1D")
+  {
+    constexpr size_t Dimension = 1;
+    using ConnectivityType     = Connectivity<Dimension>;
+
+    const ConnectivityType& connectivity = MeshDataBaseForTests::get().unordered1DMesh()->connectivity();
+
+    SECTION("synchonize NodeValue")
+    {
+      const auto node_owner  = connectivity.nodeOwner();
+      const auto node_number = connectivity.nodeNumber();
+
+      NodeValue<int> node_value_ref{connectivity};
+      parallel_for(
+        connectivity.numberOfNodes(),
+        PUGS_LAMBDA(const NodeId node_id) { node_value_ref[node_id] = node_owner[node_id] + node_number[node_id]; });
+
+      NodeValue<int> node_value{connectivity};
+      parallel_for(
+        connectivity.numberOfNodes(),
+        PUGS_LAMBDA(const NodeId node_id) { node_value[node_id] = parallel::rank() + node_number[node_id]; });
+
+      if (parallel::size() > 1) {
+        REQUIRE(not is_same_item_value(node_value, node_value_ref));
+      }
+
+      Synchronizer synchronizer;
+      synchronizer.synchronize(node_value);
+
+      REQUIRE(is_same_item_value(node_value, node_value_ref));
+    }
+
+    SECTION("synchonize EdgeValue")
+    {
+      const auto edge_owner  = connectivity.edgeOwner();
+      const auto edge_number = connectivity.edgeNumber();
+
+      EdgeValue<int> edge_value_ref{connectivity};
+      parallel_for(
+        connectivity.numberOfEdges(),
+        PUGS_LAMBDA(const EdgeId edge_id) { edge_value_ref[edge_id] = edge_owner[edge_id] + edge_number[edge_id]; });
+
+      EdgeValue<int> edge_value{connectivity};
+      parallel_for(
+        connectivity.numberOfEdges(),
+        PUGS_LAMBDA(const EdgeId edge_id) { edge_value[edge_id] = parallel::rank() + edge_number[edge_id]; });
+
+      if (parallel::size() > 1) {
+        REQUIRE(not is_same_item_value(edge_value, edge_value_ref));
+      }
+
+      Synchronizer synchronizer;
+      synchronizer.synchronize(edge_value);
+
+      REQUIRE(is_same_item_value(edge_value, edge_value_ref));
+    }
+
+    SECTION("synchonize FaceValue")
+    {
+      const auto face_owner  = connectivity.faceOwner();
+      const auto face_number = connectivity.faceNumber();
+
+      FaceValue<int> face_value_ref{connectivity};
+      parallel_for(
+        connectivity.numberOfFaces(),
+        PUGS_LAMBDA(const FaceId face_id) { face_value_ref[face_id] = face_owner[face_id] + face_number[face_id]; });
+
+      FaceValue<int> face_value{connectivity};
+      parallel_for(
+        connectivity.numberOfFaces(),
+        PUGS_LAMBDA(const FaceId face_id) { face_value[face_id] = parallel::rank() + face_number[face_id]; });
+
+      if (parallel::size() > 1) {
+        REQUIRE(not is_same_item_value(face_value, face_value_ref));
+      }
+
+      Synchronizer synchronizer;
+      synchronizer.synchronize(face_value);
+
+      REQUIRE(is_same_item_value(face_value, face_value_ref));
+    }
+
+    SECTION("synchonize CellValue")
+    {
+      const auto cell_owner  = connectivity.cellOwner();
+      const auto cell_number = connectivity.cellNumber();
+
+      CellValue<int> cell_value_ref{connectivity};
+      parallel_for(
+        connectivity.numberOfCells(),
+        PUGS_LAMBDA(const CellId cell_id) { cell_value_ref[cell_id] = cell_owner[cell_id] + cell_number[cell_id]; });
+
+      CellValue<int> cell_value{connectivity};
+      parallel_for(
+        connectivity.numberOfCells(),
+        PUGS_LAMBDA(const CellId cell_id) { cell_value[cell_id] = parallel::rank() + cell_number[cell_id]; });
+
+      if (parallel::size() > 1) {
+        REQUIRE(not is_same_item_value(cell_value, cell_value_ref));
+      }
+
+      Synchronizer synchronizer;
+      synchronizer.synchronize(cell_value);
+
+      REQUIRE(is_same_item_value(cell_value, cell_value_ref));
+    }
+
+    SECTION("synchonize CellArray")
+    {
+      const auto cell_owner  = connectivity.cellOwner();
+      const auto cell_number = connectivity.cellNumber();
+
+      CellArray<int> cell_array_ref{connectivity, 3};
+      parallel_for(
+        connectivity.numberOfCells(), PUGS_LAMBDA(const CellId cell_id) {
+          for (size_t i = 0; i < cell_array_ref.sizeOfArrays(); ++i) {
+            cell_array_ref[cell_id][i] = (i + 1) * cell_owner[cell_id] + i + cell_number[cell_id];
+          }
+        });
+
+      CellArray<int> cell_array{connectivity, 3};
+      parallel_for(
+        connectivity.numberOfCells(), PUGS_LAMBDA(const CellId cell_id) {
+          for (size_t i = 0; i < cell_array.sizeOfArrays(); ++i) {
+            cell_array[cell_id][i] = (i + 1) * parallel::rank() + i + cell_number[cell_id];
+          }
+        });
+
+      if (parallel::size() > 1) {
+        REQUIRE(not is_same_item_array(cell_array, cell_array_ref));
+      }
+
+      Synchronizer synchronizer;
+      synchronizer.synchronize(cell_array);
+
+      REQUIRE(is_same_item_array(cell_array, cell_array_ref));
+    }
+  }
+
+  SECTION("2D")
+  {
+    constexpr size_t Dimension = 2;
+    using ConnectivityType     = Connectivity<Dimension>;
+
+    const ConnectivityType& connectivity = MeshDataBaseForTests::get().hybrid2DMesh()->connectivity();
+
+    SECTION("synchonize NodeValue")
+    {
+      const auto node_owner  = connectivity.nodeOwner();
+      const auto node_number = connectivity.nodeNumber();
+
+      NodeValue<int> node_value_ref{connectivity};
+      parallel_for(
+        connectivity.numberOfNodes(),
+        PUGS_LAMBDA(const NodeId node_id) { node_value_ref[node_id] = node_owner[node_id] + node_number[node_id]; });
+
+      NodeValue<int> node_value{connectivity};
+      parallel_for(
+        connectivity.numberOfNodes(),
+        PUGS_LAMBDA(const NodeId node_id) { node_value[node_id] = parallel::rank() + node_number[node_id]; });
+
+      if (parallel::size() > 1) {
+        REQUIRE(not is_same_item_value(node_value, node_value_ref));
+      }
+
+      Synchronizer synchronizer;
+      synchronizer.synchronize(node_value);
+
+      REQUIRE(is_same_item_value(node_value, node_value_ref));
+    }
+
+    SECTION("synchonize EdgeValue")
+    {
+      const auto edge_owner  = connectivity.edgeOwner();
+      const auto edge_number = connectivity.edgeNumber();
+
+      EdgeValue<int> edge_value_ref{connectivity};
+      parallel_for(
+        connectivity.numberOfEdges(),
+        PUGS_LAMBDA(const EdgeId edge_id) { edge_value_ref[edge_id] = edge_owner[edge_id] + edge_number[edge_id]; });
+
+      EdgeValue<int> edge_value{connectivity};
+      parallel_for(
+        connectivity.numberOfEdges(),
+        PUGS_LAMBDA(const EdgeId edge_id) { edge_value[edge_id] = parallel::rank() + edge_number[edge_id]; });
+
+      if (parallel::size() > 1) {
+        REQUIRE(not is_same_item_value(edge_value, edge_value_ref));
+      }
+
+      Synchronizer synchronizer;
+      synchronizer.synchronize(edge_value);
+
+      REQUIRE(is_same_item_value(edge_value, edge_value_ref));
+    }
+
+    SECTION("synchonize FaceValue")
+    {
+      const auto face_owner  = connectivity.faceOwner();
+      const auto face_number = connectivity.faceNumber();
+
+      FaceValue<int> face_value_ref{connectivity};
+      parallel_for(
+        connectivity.numberOfFaces(),
+        PUGS_LAMBDA(const FaceId face_id) { face_value_ref[face_id] = face_owner[face_id] + face_number[face_id]; });
+
+      FaceValue<int> face_value{connectivity};
+      parallel_for(
+        connectivity.numberOfFaces(),
+        PUGS_LAMBDA(const FaceId face_id) { face_value[face_id] = parallel::rank() + face_number[face_id]; });
+
+      if (parallel::size() > 1) {
+        REQUIRE(not is_same_item_value(face_value, face_value_ref));
+      }
+
+      Synchronizer synchronizer;
+      synchronizer.synchronize(face_value);
+
+      REQUIRE(is_same_item_value(face_value, face_value_ref));
+    }
+
+    SECTION("synchonize CellValue")
+    {
+      const auto cell_owner  = connectivity.cellOwner();
+      const auto cell_number = connectivity.cellNumber();
+
+      CellValue<int> cell_value_ref{connectivity};
+      parallel_for(
+        connectivity.numberOfCells(),
+        PUGS_LAMBDA(const CellId cell_id) { cell_value_ref[cell_id] = cell_owner[cell_id] + cell_number[cell_id]; });
+
+      CellValue<int> cell_value{connectivity};
+      parallel_for(
+        connectivity.numberOfCells(),
+        PUGS_LAMBDA(const CellId cell_id) { cell_value[cell_id] = parallel::rank() + cell_number[cell_id]; });
+
+      if (parallel::size() > 1) {
+        REQUIRE(not is_same_item_value(cell_value, cell_value_ref));
+      }
+
+      Synchronizer synchronizer;
+      synchronizer.synchronize(cell_value);
+
+      REQUIRE(is_same_item_value(cell_value, cell_value_ref));
+    }
+
+    SECTION("synchonize CellArray")
+    {
+      const auto cell_owner  = connectivity.cellOwner();
+      const auto cell_number = connectivity.cellNumber();
+
+      CellArray<int> cell_array_ref{connectivity, 3};
+      parallel_for(
+        connectivity.numberOfCells(), PUGS_LAMBDA(const CellId cell_id) {
+          for (size_t i = 0; i < cell_array_ref.sizeOfArrays(); ++i) {
+            cell_array_ref[cell_id][i] = (i + 1) * cell_owner[cell_id] + i + cell_number[cell_id];
+          }
+        });
+
+      CellArray<int> cell_array{connectivity, 3};
+      parallel_for(
+        connectivity.numberOfCells(), PUGS_LAMBDA(const CellId cell_id) {
+          for (size_t i = 0; i < cell_array.sizeOfArrays(); ++i) {
+            cell_array[cell_id][i] = (i + 1) * parallel::rank() + i + cell_number[cell_id];
+          }
+        });
+
+      if (parallel::size() > 1) {
+        REQUIRE(not is_same_item_array(cell_array, cell_array_ref));
+      }
+
+      Synchronizer synchronizer;
+      synchronizer.synchronize(cell_array);
+
+      REQUIRE(is_same_item_array(cell_array, cell_array_ref));
+    }
+  }
+
+  SECTION("3D")
+  {
+    constexpr size_t Dimension = 3;
+    using ConnectivityType     = Connectivity<Dimension>;
+
+    const ConnectivityType& connectivity = MeshDataBaseForTests::get().hybrid3DMesh()->connectivity();
+
+    SECTION("synchonize NodeValue")
+    {
+      const auto node_owner  = connectivity.nodeOwner();
+      const auto node_number = connectivity.nodeNumber();
+
+      NodeValue<int> node_value_ref{connectivity};
+      parallel_for(
+        connectivity.numberOfNodes(),
+        PUGS_LAMBDA(const NodeId node_id) { node_value_ref[node_id] = node_owner[node_id] + node_number[node_id]; });
+
+      NodeValue<int> node_value{connectivity};
+      parallel_for(
+        connectivity.numberOfNodes(),
+        PUGS_LAMBDA(const NodeId node_id) { node_value[node_id] = parallel::rank() + node_number[node_id]; });
+
+      if (parallel::size() > 1) {
+        REQUIRE(not is_same_item_value(node_value, node_value_ref));
+      }
+
+      Synchronizer synchronizer;
+      synchronizer.synchronize(node_value);
+
+      REQUIRE(is_same_item_value(node_value, node_value_ref));
+    }
+
+    SECTION("synchonize EdgeValue")
+    {
+      const auto edge_owner  = connectivity.edgeOwner();
+      const auto edge_number = connectivity.edgeNumber();
+
+      EdgeValue<int> edge_value_ref{connectivity};
+      parallel_for(
+        connectivity.numberOfEdges(),
+        PUGS_LAMBDA(const EdgeId edge_id) { edge_value_ref[edge_id] = edge_owner[edge_id] + edge_number[edge_id]; });
+
+      EdgeValue<int> edge_value{connectivity};
+      parallel_for(
+        connectivity.numberOfEdges(),
+        PUGS_LAMBDA(const EdgeId edge_id) { edge_value[edge_id] = parallel::rank() + edge_number[edge_id]; });
+
+      if (parallel::size() > 1) {
+        REQUIRE(not is_same_item_value(edge_value, edge_value_ref));
+      }
+
+      Synchronizer synchronizer;
+      synchronizer.synchronize(edge_value);
+
+      REQUIRE(is_same_item_value(edge_value, edge_value_ref));
+    }
+
+    SECTION("synchonize FaceValue")
+    {
+      const auto face_owner  = connectivity.faceOwner();
+      const auto face_number = connectivity.faceNumber();
+
+      FaceValue<int> face_value_ref{connectivity};
+      parallel_for(
+        connectivity.numberOfFaces(),
+        PUGS_LAMBDA(const FaceId face_id) { face_value_ref[face_id] = face_owner[face_id] + face_number[face_id]; });
+
+      FaceValue<int> face_value{connectivity};
+      parallel_for(
+        connectivity.numberOfFaces(),
+        PUGS_LAMBDA(const FaceId face_id) { face_value[face_id] = parallel::rank() + face_number[face_id]; });
+
+      if (parallel::size() > 1) {
+        REQUIRE(not is_same_item_value(face_value, face_value_ref));
+      }
+
+      Synchronizer synchronizer;
+      synchronizer.synchronize(face_value);
+
+      REQUIRE(is_same_item_value(face_value, face_value_ref));
+    }
+
+    SECTION("synchonize CellValue")
+    {
+      const auto cell_owner  = connectivity.cellOwner();
+      const auto cell_number = connectivity.cellNumber();
+
+      CellValue<int> cell_value_ref{connectivity};
+      parallel_for(
+        connectivity.numberOfCells(),
+        PUGS_LAMBDA(const CellId cell_id) { cell_value_ref[cell_id] = cell_owner[cell_id] + cell_number[cell_id]; });
+
+      CellValue<int> cell_value{connectivity};
+      parallel_for(
+        connectivity.numberOfCells(),
+        PUGS_LAMBDA(const CellId cell_id) { cell_value[cell_id] = parallel::rank() + cell_number[cell_id]; });
+
+      if (parallel::size() > 1) {
+        REQUIRE(not is_same_item_value(cell_value, cell_value_ref));
+      }
+
+      Synchronizer synchronizer;
+      synchronizer.synchronize(cell_value);
+
+      REQUIRE(is_same_item_value(cell_value, cell_value_ref));
+    }
+
+    SECTION("synchonize CellArray")
+    {
+      const auto cell_owner  = connectivity.cellOwner();
+      const auto cell_number = connectivity.cellNumber();
+
+      CellArray<int> cell_array_ref{connectivity, 3};
+      parallel_for(
+        connectivity.numberOfCells(), PUGS_LAMBDA(const CellId cell_id) {
+          for (size_t i = 0; i < cell_array_ref.sizeOfArrays(); ++i) {
+            cell_array_ref[cell_id][i] = (i + 1) * cell_owner[cell_id] + i + cell_number[cell_id];
+          }
+        });
+
+      CellArray<int> cell_array{connectivity, 3};
+      parallel_for(
+        connectivity.numberOfCells(), PUGS_LAMBDA(const CellId cell_id) {
+          for (size_t i = 0; i < cell_array.sizeOfArrays(); ++i) {
+            cell_array[cell_id][i] = (i + 1) * parallel::rank() + i + cell_number[cell_id];
+          }
+        });
+
+      if (parallel::size() > 1) {
+        REQUIRE(not is_same_item_array(cell_array, cell_array_ref));
+      }
+
+      Synchronizer synchronizer;
+      synchronizer.synchronize(cell_array);
+
+      REQUIRE(is_same_item_array(cell_array, cell_array_ref));
+    }
+  }
+}