diff --git a/src/Makefile.am b/src/Makefile.am
index 0fdc51571424e2a9ad91d1d7c714d91446702161..c71cbbbbd1b1463a61e8b138fb85525d74ebbe03 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -41,7 +41,7 @@ include_HEADERS = space.h runner.h queue.h task.h lock.h cell.h part.h const.h \
 AM_SOURCES = space.c runner.c queue.c task.c cell.c engine.c \
     serial_io.c timers.c debug.c scheduler.c proxy.c parallel_io.c \
     units.c common_io.c single_io.c multipole.c version.c map.c \
-    kernel.c tools.c
+    kernel.c tools.c part.c
 
 # Include files for distribution, not installation.
 noinst_HEADERS = atomic.h cycle.h error.h inline.h kernel.h vector.h \
diff --git a/src/engine.c b/src/engine.c
index d0a80854a7de6c5e58df131288792e4dc312ce53..cd4d6944ef43f1ac6d580384cb3a616e7644a03f 100644
--- a/src/engine.c
+++ b/src/engine.c
@@ -47,6 +47,7 @@
 #include "cycle.h"
 #include "debug.h"
 #include "error.h"
+#include "part.h"
 #include "timers.h"
 
 #ifdef LEGACY_GADGET2_SPH
@@ -215,28 +216,24 @@ void engine_redistribute(struct engine *e) {
         offset_send += counts[ind_send];
         offset_recv += counts[ind_recv];
       } else {
-        if (MPI_Isend(&s->parts[offset_send],
-                      sizeof(struct part) * counts[ind_send], MPI_BYTE, k,
-                      2 * ind_send + 0, MPI_COMM_WORLD,
+        if (MPI_Isend(&s->parts[offset_send], counts[ind_send],
+                      e->part_mpi_type, k, 2 * ind_send + 0, MPI_COMM_WORLD,
                       &reqs[4 * k]) != MPI_SUCCESS)
           error("Failed to isend parts to node %i.", k);
-        if (MPI_Isend(&s->xparts[offset_send],
-                      sizeof(struct xpart) * counts[ind_send], MPI_BYTE, k,
-                      2 * ind_send + 1, MPI_COMM_WORLD,
+        if (MPI_Isend(&s->xparts[offset_send], counts[ind_send],
+                      e->xpart_mpi_type, k, 2 * ind_send + 1, MPI_COMM_WORLD,
                       &reqs[4 * k + 1]) != MPI_SUCCESS)
           error("Failed to isend xparts to node %i.", k);
         offset_send += counts[ind_send];
       }
     }
     if (k != nodeID && counts[ind_recv] > 0) {
-      if (MPI_Irecv(&parts_new[offset_recv],
-                    sizeof(struct part) * counts[ind_recv], MPI_BYTE, k,
-                    2 * ind_recv + 0, MPI_COMM_WORLD,
+      if (MPI_Irecv(&parts_new[offset_recv], counts[ind_recv], e->part_mpi_type,
+                    k, 2 * ind_recv + 0, MPI_COMM_WORLD,
                     &reqs[4 * k + 2]) != MPI_SUCCESS)
         error("Failed to emit irecv of parts from node %i.", k);
-      if (MPI_Irecv(&xparts_new[offset_recv],
-                    sizeof(struct xpart) * counts[ind_recv], MPI_BYTE, k,
-                    2 * ind_recv + 1, MPI_COMM_WORLD,
+      if (MPI_Irecv(&xparts_new[offset_recv], counts[ind_recv],
+                    e->xpart_mpi_type, k, 2 * ind_recv + 1, MPI_COMM_WORLD,
                     &reqs[4 * k + 3]) != MPI_SUCCESS)
         error("Failed to emit irecv of parts from node %i.", k);
       offset_recv += counts[ind_recv];
@@ -2190,7 +2187,7 @@ void engine_init(struct engine *e, struct space *s, float dt, int nr_threads,
 
   /* Are we doing stuff in parallel? */
   if (nr_nodes > 1) {
-#ifndef HAVE_MPI
+#ifndef WITH_MPI
     error("SWIFT was not compiled with MPI support.");
 #else
     e->policy |= engine_policy_mpi;
@@ -2202,6 +2199,12 @@ void engine_init(struct engine *e, struct space *s, float dt, int nr_threads,
 #endif
   }
 
+/* Construct types for MPI communications */
+#ifdef WITH_MPI
+  part_create_mpi_type(&e->part_mpi_type);
+  xpart_create_mpi_type(&e->xpart_mpi_type);
+#endif
+
   /* First of all, init the barrier and lock it. */
   if (pthread_mutex_init(&e->barrier_mutex, NULL) != 0)
     error("Failed to initialize barrier mutex.");
diff --git a/src/engine.h b/src/engine.h
index 4da743f3151704b2d32a6086352957e4d947bfc6..017455dc7da812f20703686e5d6b4715862546f1 100644
--- a/src/engine.h
+++ b/src/engine.h
@@ -19,6 +19,14 @@
 #ifndef SWIFT_ENGINE_H
 #define SWIFT_ENGINE_H
 
+/* Config parameters. */
+#include "../config.h"
+
+/* MPI headers. */
+#ifdef WITH_MPI
+#include <mpi.h>
+#endif
+
 /* Some standard headers. */
 #include <pthread.h>
 
@@ -125,6 +133,12 @@ struct engine {
   /* Linked list for cell-task association. */
   struct link *links;
   int nr_links, size_links;
+
+#ifdef WITH_MPI
+  /* MPI data type for the particle transfers */
+  MPI_Datatype part_mpi_type;
+  MPI_Datatype xpart_mpi_type;
+#endif
 };
 
 /* Function prototypes. */
diff --git a/src/part.c b/src/part.c
new file mode 100644
index 0000000000000000000000000000000000000000..6d49887ad72d6afdd1f419cfdaca88090e781f3e
--- /dev/null
+++ b/src/part.c
@@ -0,0 +1,68 @@
+/*******************************************************************************
+ * This file is part of SWIFT.
+ * Copyright (c) 2016 Matthieu Schaller (matthieu.schaller@durham.ac.uk)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ ******************************************************************************/
+
+/* Config parameters. */
+#include "../config.h"
+
+/* MPI headers. */
+#ifdef WITH_MPI
+#include <mpi.h>
+#endif
+
+/* This object's header. */
+#include "part.h"
+
+#ifdef WITH_MPI
+/**
+ * @brief Registers and returns an MPI type for the particles
+ *
+ * @param part_type The type container
+ */
+void part_create_mpi_type(MPI_Datatype* part_type) {
+
+  /* This is not the recommended way of doing this.
+     One should define the structure field by field
+     But as long as we don't do serialization via MPI-IO
+     we don't really care.
+     Also we would have to modify this function everytime something
+     is added to the part structure. */
+  MPI_Type_contiguous(sizeof(struct part) / sizeof(unsigned char), MPI_BYTE,
+                      part_type);
+  MPI_Type_commit(part_type);
+}
+
+/**
+ * @brief Registers and returns an MPI type for the xparticles
+ *
+ * @param xpart_type The type container
+ */
+void xpart_create_mpi_type(MPI_Datatype* xpart_type) {
+
+  /* This is not the recommended way of doing this.
+     One should define the structure field by field 
+     But as long as we don't do serialization via MPI-IO 
+     we don't really care. 
+     Also we would have to modify this function everytime something 
+     is added to the part structure. */
+  MPI_Type_contiguous(sizeof(struct xpart) / sizeof(unsigned char), MPI_BYTE,
+                      xpart_type);
+  MPI_Type_commit(xpart_type);
+}
+
+#endif
diff --git a/src/part.h b/src/part.h
index 1ad62888b3accd38c6c3f5e13f49988d2c6d69d1..e2940e29c1b008b55efbb7dfa178bae80c134add 100644
--- a/src/part.h
+++ b/src/part.h
@@ -19,6 +19,18 @@
 #ifndef SWIFT_PART_H
 #define SWIFT_PART_H
 
+/* Config parameters. */
+#include "../config.h"
+
+/* Some standard headers. */
+#include <stdlib.h>
+
+/* MPI headers. */
+#ifdef WITH_MPI
+#include <mpi.h>
+#endif
+
+/* Local headers. */
 #include "const.h"
 
 /* Some constants. */
@@ -72,7 +84,7 @@ struct gpart {
     size_t id;
 
     /* Pointer to corresponding SPH part. */
-    struct part *part;
+    struct part* part;
   };
 
 } __attribute__((aligned(part_align)));
@@ -162,8 +174,13 @@ struct part {
   unsigned long long id;
 
   /* Associated gravitas. */
-  struct gpart *gpart;
+  struct gpart* gpart;
 
 } __attribute__((aligned(part_align)));
 
+#ifdef WITH_MPI
+void part_create_mpi_type(MPI_Datatype* part_type);
+void xpart_create_mpi_type(MPI_Datatype* xpart_type);
+#endif
+
 #endif /* SWIFT_PART_H */
diff --git a/src/scheduler.c b/src/scheduler.c
index ae83ddc0ff5a0fcf65f515fe61ba40cdeb26be96..7b26b866a6d9d376cb18ad9c25979bf95a296ae5 100644
--- a/src/scheduler.c
+++ b/src/scheduler.c
@@ -1048,8 +1048,8 @@ void scheduler_enqueue(struct scheduler *s, struct task *t) {
         break;
       case task_type_recv:
 #ifdef WITH_MPI
-        if ((err = MPI_Irecv(t->ci->parts, sizeof(struct part) * t->ci->count,
-                             MPI_BYTE, t->ci->nodeID, t->flags, MPI_COMM_WORLD,
+        if ((err = MPI_Irecv(t->ci->parts, t->ci->count, s->part_mpi_type,
+                             t->ci->nodeID, t->flags, MPI_COMM_WORLD,
                              &t->req)) != MPI_SUCCESS) {
           char buff[MPI_MAX_ERROR_STRING];
           int len;
@@ -1066,9 +1066,9 @@ void scheduler_enqueue(struct scheduler *s, struct task *t) {
         break;
       case task_type_send:
 #ifdef WITH_MPI
-        if ((err = MPI_Isend(t->ci->parts, sizeof(struct part) * t->ci->count,
-                             MPI_BYTE, t->cj->nodeID, t->flags, MPI_COMM_WORLD,
-                             &t->req)) != MPI_SUCCESS) {
+        if ((err = MPI_Isend(t->ci->parts, t->ci->count, s->part_mpi_type, 
+			     t->cj->nodeID, t->flags, MPI_COMM_WORLD, 
+			     &t->req)) != MPI_SUCCESS) {
           char buff[MPI_MAX_ERROR_STRING];
           int len;
           MPI_Error_string(err, buff, &len);
@@ -1306,4 +1306,10 @@ void scheduler_init(struct scheduler *s, struct space *space, int nr_tasks,
   s->tasks = NULL;
   s->tasks_ind = NULL;
   scheduler_reset(s, nr_tasks);
+
+/* Construct types for MPI communications */
+#ifdef WITH_MPI
+  part_create_mpi_type(&s->part_mpi_type);
+  xpart_create_mpi_type(&s->xpart_mpi_type);
+#endif
 }
diff --git a/src/scheduler.h b/src/scheduler.h
index 9bdb9b27da4089723dfcd6e93912f958f4811ab6..08aadf5454525f11a5cbb5ef8cb0f4c135aa1ad2 100644
--- a/src/scheduler.h
+++ b/src/scheduler.h
@@ -20,6 +20,14 @@
 #ifndef SWIFT_SCHEDULER_H
 #define SWIFT_SCHEDULER_H
 
+/* Config parameters. */
+#include "../config.h"
+
+/* MPI headers. */
+#ifdef WITH_MPI
+#include <mpi.h>
+#endif
+
 /* Some standard headers. */
 #include <pthread.h>
 
@@ -89,6 +97,12 @@ struct scheduler {
 
   /* The node we are working on. */
   int nodeID;
+
+#ifdef WITH_MPI
+  /* MPI data type for the particle transfers */
+  MPI_Datatype part_mpi_type;
+  MPI_Datatype xpart_mpi_type;
+#endif
 };
 
 /* Function prototypes. */