diff --git a/CMakeLists.txt b/CMakeLists.txt
index 95f96478b331b3790fb57946a031cea15fe73d67..a4aa863b266890293cb48ceaf21990120f4d303b 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -113,6 +113,16 @@ if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
   endif()
 endif()
 
+#------------------------------------------------------
+
+include (TestBigEndian)
+TEST_BIG_ENDIAN(IS_BIG_ENDIAN)
+if(IS_BIG_ENDIAN)
+  set(PUGS_LITTLE_ENDIAN FALSE)
+else()
+  set(PUGS_LITTLE_ENDIAN TRUE)
+endif()
+
 #------------------------------------------------------
 # defaults use of MPI
 set(PUGS_ENABLE_MPI AUTO CACHE STRING
diff --git a/src/output/VTKWriter.cpp b/src/output/VTKWriter.cpp
index f1f87e9cd5969b576d68f3e98551fcc72c12e847..f65a4acfa89830c54e131539252e80a08de67ff3 100644
--- a/src/output/VTKWriter.cpp
+++ b/src/output/VTKWriter.cpp
@@ -6,6 +6,7 @@
 #include <mesh/MeshDataManager.hpp>
 #include <utils/Messenger.hpp>
 #include <utils/RevisionInfo.hpp>
+#include <utils/pugs_config.hpp>
 
 #include <ctime>
 #include <fstream>
@@ -13,6 +14,99 @@
 #include <sstream>
 #include <unordered_map>
 
+class ICharArrayEmbedder
+{
+ public:
+  ICharArrayEmbedder()                          = default;
+  ICharArrayEmbedder(const ICharArrayEmbedder&) = default;
+  ICharArrayEmbedder(ICharArrayEmbedder&&)      = default;
+
+  virtual size_t size() const             = 0;
+  virtual void write(std::ostream&) const = 0;
+
+  virtual ~ICharArrayEmbedder() = default;
+};
+
+template <typename InputDataT>
+class CharArrayEmbedder : public ICharArrayEmbedder
+{
+  CastArray<InputDataT, char> m_char_cast_array;
+
+ public:
+  size_t
+  size() const final
+  {
+    return m_char_cast_array.size();
+  }
+
+  void
+  write(std::ostream& os) const final
+  {
+    os.write(&(m_char_cast_array[0]), m_char_cast_array.size());
+  }
+
+  CharArrayEmbedder(Array<InputDataT> array) : m_char_cast_array{array} {}
+
+  CharArrayEmbedder()                         = default;
+  CharArrayEmbedder(const CharArrayEmbedder&) = default;
+  CharArrayEmbedder(CharArrayEmbedder&&)      = default;
+
+  ~CharArrayEmbedder() = default;
+};
+
+class VTKWriter::SerializedDataList
+{
+ private:
+  std::vector<std::shared_ptr<ICharArrayEmbedder>> m_serialized_data_list;
+  size_t m_offset = 0;
+
+ public:
+  size_t
+  offset() const
+  {
+    return m_offset;
+  }
+
+  template <typename DataT>
+  void
+  add(Array<DataT> array)
+  {
+    auto array_data = std::make_shared<CharArrayEmbedder<DataT>>(array);
+    auto size_data  = std::make_shared<CharArrayEmbedder<int>>([&] {
+      Array<int> size_array(1);
+      size_array[0] = array_data->size();
+      return size_array;
+    }());
+
+    m_serialized_data_list.push_back(size_data);
+    m_serialized_data_list.push_back(array_data);
+
+    m_offset += size_data->size() + array_data->size();
+  }
+
+  template <typename DataT, ItemType item_type, typename ConnectivityT>
+  void
+  add(const ItemValue<DataT, item_type, ConnectivityT>& item_value)
+  {
+    Array<std::remove_const_t<DataT>> array(item_value.numberOfItems());
+    parallel_for(
+      item_value.numberOfItems(), PUGS_LAMBDA(ItemIdT<item_type> item_id) { array[item_id] = item_value[item_id]; });
+
+    this->add(array);
+  }
+
+  void
+  write(std::ostream& os) const
+  {
+    for (auto serialized_data : m_serialized_data_list) {
+      serialized_data->write(os);
+    }
+  }
+
+  SerializedDataList()  = default;
+  ~SerializedDataList() = default;
+};
+
 std::string
 VTKWriter::_getFilenamePVTU() const
 {
@@ -134,141 +228,114 @@ struct VTKWriter::VTKType
 
 template <typename DataType>
 void
-VTKWriter::_write_array(std::ofstream& os, const std::string& name, const Array<DataType>& item_value) const
+VTKWriter::_write_array(std::ofstream& os,
+                        const std::string& name,
+                        const Array<DataType>& item_value,
+                        SerializedDataList& serialized_data_list) const
 {
-  os << "<DataArray type=\"" << VTKType<DataType>::name << "\" Name=\"" << name << "\">\n";
-  for (typename Array<DataType>::index_type i = 0; i < item_value.size(); ++i) {
-    // The following '+' enforces integer output for char types
-    os << +item_value[i] << ' ';
-  }
-  os << "\n</DataArray>\n";
+  os << "<DataArray type=\"" << VTKType<DataType>::name << "\" Name=\"" << name << "\" offset=\""
+     << serialized_data_list.offset() << "\" format=\"appended\"/>\n";
+  serialized_data_list.add(item_value);
 }
 
 template <size_t N, typename DataType>
 void
 VTKWriter::_write_array(std::ofstream& os,
                         const std::string& name,
-                        const Array<TinyVector<N, DataType>>& item_value) const
+                        const Array<TinyVector<N, DataType>>& item_value,
+                        SerializedDataList& serialized_data_list) const
 {
   os << "<DataArray type=\"" << VTKType<DataType>::name << "\" Name=\"" << name << "\" NumberOfComponents=\"" << N
-     << "\">\n";
-  for (typename Array<DataType>::index_type i = 0; i < item_value.size(); ++i) {
-    for (size_t j = 0; j < N; ++j) {
-      // The following '+' enforces integer output for char types
-      os << +item_value[i][j] << ' ';
-    }
-  }
-  os << "\n</DataArray>\n";
+     << "\" offset=\"" << serialized_data_list.offset() << "\" format=\"appended\"/>\n";
+  serialized_data_list.add(item_value);
 }
 
 template <typename DataType>
 void
 VTKWriter::_write_node_value(std::ofstream& os,
                              const std::string& name,
-                             const NodeValue<const DataType>& item_value) const
+                             const NodeValue<const DataType>& item_value,
+                             SerializedDataList& serialized_data_list) const
 {
-  os << "<DataArray type=\"" << VTKType<DataType>::name << "\" Name=\"" << name << "\">\n";
-  for (NodeId i = 0; i < item_value.size(); ++i) {
-    // The following '+' enforces integer output for char types
-    os << +item_value[i] << ' ';
-  }
-  os << "\n</DataArray>\n";
+  os << "<DataArray type=\"" << VTKType<DataType>::name << "\" Name=\"" << name << "\" offset=\""
+     << serialized_data_list.offset() << "\" format=\"appended\"/>\n";
+  serialized_data_list.add(item_value);
 }
 
 template <size_t N, typename DataType>
 void
 VTKWriter::_write_node_value(std::ofstream& os,
                              const std::string& name,
-                             const NodeValue<const TinyVector<N, DataType>>& item_value) const
+                             const NodeValue<const TinyVector<N, DataType>>& item_value,
+                             SerializedDataList& serialized_data_list) const
 {
   os << "<DataArray type=\"" << VTKType<DataType>::name << "\" Name=\"" << name << "\" NumberOfComponents=\"" << N
-     << "\">\n";
-  for (NodeId i = 0; i < item_value.size(); ++i) {
-    for (size_t j = 0; j < N; ++j) {
-      // The following '+' enforces integer output for char types
-      os << +item_value[i][j] << ' ';
-    }
-  }
-  os << "\n</DataArray>\n";
+     << "\" offset=\"" << serialized_data_list.offset() << "\" format=\"appended\"/>\n";
+  serialized_data_list.add(item_value);
 }
 
 template <size_t N, typename DataType>
 void
 VTKWriter::_write_node_value(std::ofstream& os,
                              const std::string& name,
-                             const NodeValue<const TinyMatrix<N, DataType>>& item_value) const
+                             const NodeValue<const TinyMatrix<N, DataType>>& item_value,
+                             SerializedDataList& serialized_data_list) const
 {
   os << "<DataArray type=\"" << VTKType<DataType>::name << "\" Name=\"" << name << "\" NumberOfComponents=\"" << N * N
-     << "\">\n";
-  for (NodeId i = 0; i < item_value.size(); ++i) {
-    for (size_t j = 0; j < N; ++j) {
-      for (size_t k = 0; k < N; ++k) {
-        // The following '+' enforces integer output for char types
-        os << +item_value[i](j, k) << ' ';
-      }
-    }
-  }
-  os << "\n</DataArray>\n";
+     << "\" offset=\"" << serialized_data_list.offset() << "\" format=\"appended\"/>\n";
+  serialized_data_list.add(item_value);
 }
 
 template <typename DataType>
 void
-VTKWriter::_write_node_value(std::ofstream&, const std::string&, const CellValue<const DataType>&) const
+VTKWriter::_write_node_value(std::ofstream&,
+                             const std::string&,
+                             const CellValue<const DataType>&,
+                             SerializedDataList&) const
 {}
 
 template <typename DataType>
 void
 VTKWriter::_write_cell_value(std::ofstream& os,
                              const std::string& name,
-                             const CellValue<const DataType>& item_value) const
+                             const CellValue<const DataType>& item_value,
+                             SerializedDataList& serialized_data_list) const
 {
-  os << "<DataArray type=\"" << VTKType<DataType>::name << "\" Name=\"" << name << "\">\n";
-  for (CellId i = 0; i < item_value.size(); ++i) {
-    // The following '+' enforces integer output for char types
-    os << +item_value[i] << ' ';
-  }
-  os << "\n</DataArray>\n";
+  os << "<DataArray type=\"" << VTKType<DataType>::name << "\" Name=\"" << name << "\" offset=\""
+     << serialized_data_list.offset() << "\" format=\"appended\"/>\n";
+  serialized_data_list.add(item_value);
 }
 
 template <size_t N, typename DataType>
 void
 VTKWriter::_write_cell_value(std::ofstream& os,
                              const std::string& name,
-                             const CellValue<const TinyVector<N, DataType>>& item_value) const
+                             const CellValue<const TinyVector<N, DataType>>& item_value,
+                             SerializedDataList& serialized_data_list) const
 {
   os << "<DataArray type=\"" << VTKType<DataType>::name << "\" Name=\"" << name << "\" NumberOfComponents=\"" << N
-     << "\">\n";
-  for (CellId i = 0; i < item_value.size(); ++i) {
-    for (size_t j = 0; j < N; ++j) {
-      // The following '+' enforces integer output for char types
-      os << +item_value[i][j] << ' ';
-    }
-  }
-  os << "\n</DataArray>\n";
+     << "\" offset=\"" << serialized_data_list.offset() << "\" format=\"appended\"/>\n";
+  serialized_data_list.add(item_value);
 }
 
 template <size_t N, typename DataType>
 void
 VTKWriter::_write_cell_value(std::ofstream& os,
                              const std::string& name,
-                             const CellValue<const TinyMatrix<N, DataType>>& item_value) const
+                             const CellValue<const TinyMatrix<N, DataType>>& item_value,
+                             SerializedDataList& serialized_data_list) const
 {
   os << "<DataArray type=\"" << VTKType<DataType>::name << "\" Name=\"" << name << "\" NumberOfComponents=\"" << N * N
-     << "\">\n";
-  for (CellId i = 0; i < item_value.size(); ++i) {
-    for (size_t j = 0; j < N; ++j) {
-      for (size_t k = 0; k < N; ++k) {
-        // The following '+' enforces integer output for char types
-        os << +item_value[i](j, k) << ' ';
-      }
-    }
-  }
-  os << "\n</DataArray>\n";
+     << "\" offset=\"" << serialized_data_list.offset() << "\" format=\"appended\"/>\n";
+  serialized_data_list.add(item_value);
 }
 
 template <typename DataType>
 void
-VTKWriter::_write_cell_value(std::ofstream&, const std::string&, const NodeValue<const DataType>&) const
+VTKWriter::_write_cell_value(std::ofstream&,
+                             const std::string&,
+                             const NodeValue<const DataType>&,
+                             SerializedDataList&) const
 {}
 
 template <typename MeshType>
@@ -329,23 +396,34 @@ VTKWriter::_write(const std::shared_ptr<const MeshType>& mesh,
     fout << "</VTKFile>\n";
   }
 
-  {   // write VTK files
+  {
+    SerializedDataList serialize_data_list;
+
+    // write VTK files
     std::ofstream fout(_getFilenameVTU(parallel::rank()));
     fout << "<?xml version=\"1.0\"?>\n";
     fout << _getDateAndVersionComment();
-    fout << "<VTKFile type=\"UnstructuredGrid\">\n";
+    fout << "<VTKFile type=\"UnstructuredGrid\"";
+#if defined(PUGS_LITTLE_ENDIAN)
+    fout << " byte_order=\"LittleEndian\"";
+#else
+    fout << " byte_order=\"BigEndian\"";
+#endif
+    fout << ">\n";
     fout << "<UnstructuredGrid>\n";
     fout << "<Piece NumberOfPoints=\"" << mesh->numberOfNodes() << "\" NumberOfCells=\"" << mesh->numberOfCells()
          << "\">\n";
     fout << "<CellData>\n";
     for (const auto& [name, item_value_variant] : output_named_item_value_set) {
-      std::visit([&, name = name](auto&& item_value) { return this->_write_cell_value(fout, name, item_value); },
+      std::visit([&, name = name](
+                   auto&& item_value) { return this->_write_cell_value(fout, name, item_value, serialize_data_list); },
                  item_value_variant);
     }
     fout << "</CellData>\n";
     fout << "<PointData>\n";
     for (const auto& [name, item_value_variant] : output_named_item_value_set) {
-      std::visit([&, name = name](auto&& item_value) { return this->_write_node_value(fout, name, item_value); },
+      std::visit([&, name = name](
+                   auto&& item_value) { return this->_write_node_value(fout, name, item_value, serialize_data_list); },
                  item_value_variant);
     }
     fout << "</PointData>\n";
@@ -363,7 +441,7 @@ VTKWriter::_write(const std::shared_ptr<const MeshType>& mesh,
             positions[r][i] = 0;
           }
         });
-      _write_array(fout, "Positions", positions);
+      _write_array(fout, "Positions", positions, serialize_data_list);
     }
     fout << "</Points>\n";
 
@@ -371,7 +449,7 @@ VTKWriter::_write(const std::shared_ptr<const MeshType>& mesh,
     {
       const auto& cell_to_node_matrix = mesh->connectivity().cellToNodeMatrix();
 
-      _write_array(fout, "connectivity", cell_to_node_matrix.entries());
+      _write_array(fout, "connectivity", cell_to_node_matrix.entries(), serialize_data_list);
     }
 
     {
@@ -383,7 +461,7 @@ VTKWriter::_write(const std::shared_ptr<const MeshType>& mesh,
         offset += cell_nodes.size();
         offsets[j] = offset;
       }
-      _write_array(fout, "offsets", offsets);
+      _write_array(fout, "offsets", offsets, serialize_data_list);
     }
 
     {
@@ -437,7 +515,7 @@ VTKWriter::_write(const std::shared_ptr<const MeshType>& mesh,
           }
           }
         });
-      _write_array(fout, "types", types);
+      _write_array(fout, "types", types, serialize_data_list);
       if constexpr (MeshType::Dimension == 3) {
         const bool has_general_polyhedron = [&] {
           for (size_t i = 0; i < types.size(); ++i) {
@@ -507,6 +585,11 @@ VTKWriter::_write(const std::shared_ptr<const MeshType>& mesh,
     fout << "</Cells>\n";
     fout << "</Piece>\n";
     fout << "</UnstructuredGrid>\n";
+    fout << "<AppendedData encoding=\"raw\">\n";
+    fout << "_";
+    serialize_data_list.write(fout);
+    fout << '\n';
+    fout << "</AppendedData>\n";
     fout << "</VTKFile>\n";
   }
 
diff --git a/src/output/VTKWriter.hpp b/src/output/VTKWriter.hpp
index 704ba63f990ead2b6b8e8f64cafdda627c2be64b..7f38119222474af2df46508e96fb27d7a40053f9 100644
--- a/src/output/VTKWriter.hpp
+++ b/src/output/VTKWriter.hpp
@@ -14,6 +14,8 @@ class IMesh;
 class VTKWriter : public WriterBase
 {
  private:
+  class SerializedDataList;
+
   std::string _getDateAndVersionComment() const;
 
   std::string _getFilenamePVTU() const;
@@ -56,42 +58,64 @@ class VTKWriter : public WriterBase
   struct VTKType;
 
   template <typename DataType>
-  void _write_array(std::ofstream& os, const std::string& name, const Array<DataType>& item_value) const;
+  void _write_array(std::ofstream& os,
+                    const std::string& name,
+                    const Array<DataType>& item_value,
+                    SerializedDataList& serialized_data_list) const;
 
   template <size_t N, typename DataType>
-  void _write_array(std::ofstream& os, const std::string& name, const Array<TinyVector<N, DataType>>& item_value) const;
+  void _write_array(std::ofstream& os,
+                    const std::string& name,
+                    const Array<TinyVector<N, DataType>>& item_value,
+                    SerializedDataList& serialized_data_list) const;
 
   template <typename DataType>
-  void _write_node_value(std::ofstream& os, const std::string& name, const NodeValue<const DataType>& item_value) const;
+  void _write_node_value(std::ofstream& os,
+                         const std::string& name,
+                         const NodeValue<const DataType>& item_value,
+                         SerializedDataList& serialized_data_list) const;
 
   template <size_t N, typename DataType>
   void _write_node_value(std::ofstream& os,
                          const std::string& name,
-                         const NodeValue<const TinyVector<N, DataType>>& item_value) const;
+                         const NodeValue<const TinyVector<N, DataType>>& item_value,
+                         SerializedDataList& serialized_data_list) const;
 
   template <size_t N, typename DataType>
   void _write_node_value(std::ofstream& os,
                          const std::string& name,
-                         const NodeValue<const TinyMatrix<N, DataType>>& item_value) const;
+                         const NodeValue<const TinyMatrix<N, DataType>>& item_value,
+                         SerializedDataList& serialized_data_list) const;
 
   template <typename DataType>
-  void _write_node_value(std::ofstream&, const std::string&, const CellValue<const DataType>&) const;
+  void _write_node_value(std::ofstream&,
+                         const std::string&,
+                         const CellValue<const DataType>&,
+                         SerializedDataList&) const;
 
   template <typename DataType>
-  void _write_cell_value(std::ofstream& os, const std::string& name, const CellValue<const DataType>& item_value) const;
+  void _write_cell_value(std::ofstream& os,
+                         const std::string& name,
+                         const CellValue<const DataType>& item_value,
+                         SerializedDataList& serialized_data_list) const;
 
   template <size_t N, typename DataType>
   void _write_cell_value(std::ofstream& os,
                          const std::string& name,
-                         const CellValue<const TinyVector<N, DataType>>& item_value) const;
+                         const CellValue<const TinyVector<N, DataType>>& item_value,
+                         SerializedDataList& serialized_data_list) const;
 
   template <size_t N, typename DataType>
   void _write_cell_value(std::ofstream& os,
                          const std::string& name,
-                         const CellValue<const TinyMatrix<N, DataType>>& item_value) const;
+                         const CellValue<const TinyMatrix<N, DataType>>& item_value,
+                         SerializedDataList& serialized_data_list) const;
 
   template <typename DataType>
-  void _write_cell_value(std::ofstream&, const std::string&, const NodeValue<const DataType>&) const;
+  void _write_cell_value(std::ofstream&,
+                         const std::string&,
+                         const NodeValue<const DataType>&,
+                         SerializedDataList&) const;
 
   template <typename MeshType>
   void _write(const std::shared_ptr<const MeshType>& mesh,
diff --git a/src/utils/pugs_config.hpp.in b/src/utils/pugs_config.hpp.in
index de267d26e10fb41994bbc72438b57d577e4b447a..84a6d8fa0c2d50eb623d5d1c2b52765f5610de24 100644
--- a/src/utils/pugs_config.hpp.in
+++ b/src/utils/pugs_config.hpp.in
@@ -9,6 +9,8 @@
 #cmakedefine SYSTEM_IS_DARWIN
 #cmakedefine SYSTEM_IS_WINDOWS
 
+#cmakedefine PUGS_LITTLE_ENDIAN
+
 #define PUGS_BUILD_TYPE "@CMAKE_BUILD_TYPE@"
 #define PUGS_BINARY_DIR "@PUGS_BINARY_DIR@"