diff --git a/src/cell.c b/src/cell.c
index 9d192caf87474101a31cc1d7a43470f7989a838d..1036110d0cc4a552f5df884004dd5ae87e4fe79d 100644
--- a/src/cell.c
+++ b/src/cell.c
@@ -207,7 +207,9 @@ int cell_link_foreign_parts(struct cell *c, struct part *parts) {
 #endif
 
   /* Do we have a hydro task at this level? */
-  if (c->mpi.hydro.recv_xv != NULL) {
+  struct link *l = c->mpi.recv;
+  while (l != NULL && l->t->subtype != task_subtype_xv) l = l->next;
+  if (l != NULL) {
 
     /* Recursively attach the parts */
     const int counts = cell_link_parts(c, parts);
@@ -303,7 +305,9 @@ int cell_count_parts_for_tasks(const struct cell *c) {
 #endif
 
   /* Do we have a hydro task at this level? */
-  if (c->mpi.hydro.recv_xv != NULL) {
+  struct link *l = c->mpi.recv;
+  while (l != NULL && l->t->subtype != task_subtype_xv) l = l->next;
+  if (l != NULL) {
     return c->hydro.count;
   }
 
@@ -3259,7 +3263,7 @@ int cell_unskip_hydro_tasks(struct cell *c, struct scheduler *s) {
 
         /* If the local cell is active, receive data from the foreign cell. */
         if (cj_active) {
-          scheduler_activate(s, ci->mpi.hydro.recv_xv);
+          scheduler_activate_recv(s, ci->mpi.recv, task_subtype_xv);
           if (ci_active) {
             scheduler_activate(s, ci->mpi.hydro.recv_rho);
 
@@ -3309,7 +3313,7 @@ int cell_unskip_hydro_tasks(struct cell *c, struct scheduler *s) {
 
         /* If the local cell is active, receive data from the foreign cell. */
         if (ci_active) {
-          scheduler_activate(s, cj->mpi.hydro.recv_xv);
+          scheduler_activate_recv(s, cj->mpi.recv, task_subtype_xv);
           if (cj_active) {
             scheduler_activate(s, cj->mpi.hydro.recv_rho);
 
@@ -3658,7 +3662,7 @@ int cell_unskip_stars_tasks(struct cell *c, struct scheduler *s) {
       if (ci_nodeID != nodeID) {
 
         if (cj_active) {
-          scheduler_activate(s, ci->mpi.hydro.recv_xv);
+          scheduler_activate_recv(s, ci->mpi.recv, task_subtype_xv);
           scheduler_activate(s, ci->mpi.hydro.recv_rho);
 
           /* If the local cell is active, more stuff will be needed. */
@@ -3690,7 +3694,7 @@ int cell_unskip_stars_tasks(struct cell *c, struct scheduler *s) {
 
         /* If the local cell is active, receive data from the foreign cell. */
         if (ci_active) {
-          scheduler_activate(s, cj->mpi.hydro.recv_xv);
+          scheduler_activate_recv(s, cj->mpi.recv, task_subtype_xv);
           scheduler_activate(s, cj->mpi.hydro.recv_rho);
 
           /* If the local cell is active, more stuff will be needed. */
diff --git a/src/cell.h b/src/cell.h
index b5263acb2e724beef40b47a45b1180233a4061b0..c1bc2d7ed18a584de842546883504b7eb16d0f9f 100644
--- a/src/cell.h
+++ b/src/cell.h
@@ -576,14 +576,11 @@ struct cell {
       /* Single list of all send tasks associated with this cell. */
       struct link *send;
 
-      /* Single list of all recv tasks associated with this cel. */
+      /* Single list of all recv tasks associated with this cell. */
       struct link *recv;
     };
 
     struct {
-      /* Task receiving hydro data (positions). */
-      struct task *recv_xv;
-
       /* Task receiving hydro data (density). */
       struct task *recv_rho;
 
diff --git a/src/engine_maketasks.c b/src/engine_maketasks.c
index 7cfa13a5c75626df9220910a96ae2992b895f629..b1fb70fb941602c965a42faf2ba575bd878f15eb 100644
--- a/src/engine_maketasks.c
+++ b/src/engine_maketasks.c
@@ -328,7 +328,7 @@ void engine_addtasks_recv_hydro(struct engine *e, struct cell *c,
                              c->mpi.tag, 0, c, NULL);
   }
 
-  c->mpi.hydro.recv_xv = t_xv;
+  engine_addlink(e, &c->mpi.recv, t_xv);
   c->mpi.hydro.recv_rho = t_rho;
   c->mpi.hydro.recv_gradient = t_gradient;
   c->mpi.hydro.recv_ti = t_ti;
diff --git a/src/engine_marktasks.c b/src/engine_marktasks.c
index 4d689ab0e632c3249aad090a3bf329c998fc0b90..f6a70e992642a513535d7338275c8596f3c95a44 100644
--- a/src/engine_marktasks.c
+++ b/src/engine_marktasks.c
@@ -362,7 +362,7 @@ void engine_marktasks_mapper(void *map_data, int num_elements,
 
           /* If the local cell is active, receive data from the foreign cell. */
           if (cj_active_hydro) {
-            scheduler_activate(s, ci->mpi.hydro.recv_xv);
+            scheduler_activate_recv(s, ci->mpi.recv, task_subtype_xv);
             if (ci_active_hydro) {
               scheduler_activate(s, ci->mpi.hydro.recv_rho);
 #ifdef EXTRA_HYDRO_LOOP
@@ -406,7 +406,7 @@ void engine_marktasks_mapper(void *map_data, int num_elements,
           /* If the local cell is active, receive data from the foreign cell. */
           if (ci_active_hydro) {
 
-            scheduler_activate(s, cj->mpi.hydro.recv_xv);
+            scheduler_activate_recv(s, cj->mpi.recv, task_subtype_xv);
             if (cj_active_hydro) {
               scheduler_activate(s, cj->mpi.hydro.recv_rho);
 #ifdef EXTRA_HYDRO_LOOP
@@ -462,7 +462,7 @@ void engine_marktasks_mapper(void *map_data, int num_elements,
         if (ci_nodeID != nodeID) {
 
           if (cj_active_stars) {
-            scheduler_activate(s, ci->mpi.hydro.recv_xv);
+            scheduler_activate_recv(s, ci->mpi.recv, task_subtype_xv);
             scheduler_activate(s, ci->mpi.hydro.recv_rho);
 
             /* If the local cell is active, more stuff will be needed. */
@@ -496,7 +496,7 @@ void engine_marktasks_mapper(void *map_data, int num_elements,
 
           /* If the local cell is active, receive data from the foreign cell. */
           if (ci_active_stars) {
-            scheduler_activate(s, cj->mpi.hydro.recv_xv);
+            scheduler_activate_recv(s, cj->mpi.recv, task_subtype_xv);
             scheduler_activate(s, cj->mpi.hydro.recv_rho);
 
             /* If the local cell is active, more stuff will be needed. */
diff --git a/src/scheduler.h b/src/scheduler.h
index e4c03b831efbc1e8ab6eb1c9746c787da0b11468..95d6c4760b26e97b20bf2cc6edeb6bebf7b554d9 100644
--- a/src/scheduler.h
+++ b/src/scheduler.h
@@ -152,6 +152,29 @@ scheduler_activate_send(struct scheduler *s, struct link *link,
   return l;
 }
 
+/**
+ * @brief Search and add an MPI recv task to the list of active tasks.
+ *
+ * @param s The #scheduler.
+ * @param link The first element in the linked list of links for the task of
+ * interest.
+ * @param subtype the task subtype to activate.
+ *
+ * @return The #link to the MPI recv task.
+ */
+__attribute__((always_inline)) INLINE static struct link *
+scheduler_activate_recv(struct scheduler *s, struct link *link,
+                        enum task_subtypes subtype) {
+  struct link *l = NULL;
+  for (l = link; l != NULL && l->t->subtype != subtype; l = l->next)
+    ;
+  if (l == NULL) {
+    error("Missing link to recv task.");
+  }
+  scheduler_activate(s, l->t);
+  return l;
+}
+
 /* Function prototypes. */
 void scheduler_clear_active(struct scheduler *s);
 void scheduler_init(struct scheduler *s, struct space *space, int nr_tasks,
diff --git a/src/space.c b/src/space.c
index 185d9e59518c7a715344e3732f548ffb6e20e608..cb63e86bd0049dbbd696632db4581885447af39d 100644
--- a/src/space.c
+++ b/src/space.c
@@ -268,7 +268,7 @@ void space_rebuild_recycle_mapper(void *map_data, int num_elements,
 #if WITH_MPI
     c->mpi.tag = -1;
 
-    c->mpi.hydro.recv_xv = NULL;
+    c->mpi.recv = NULL;
     c->mpi.hydro.recv_rho = NULL;
     c->mpi.hydro.recv_gradient = NULL;
     c->mpi.hydro.recv_ti = NULL;
@@ -577,7 +577,7 @@ void space_regrid(struct space *s, int verbose) {
           c->grav.ti_old_multipole = ti_current;
 #ifdef WITH_MPI
           c->mpi.tag = -1;
-          c->mpi.hydro.recv_xv = NULL;
+          c->mpi.recv = NULL;
           c->mpi.hydro.recv_rho = NULL;
           c->mpi.hydro.recv_gradient = NULL;
           c->mpi.send = NULL;