diff --git a/src/cell.c b/src/cell.c
index bdec2dfebd84cf6421ba32311bcbbcf4b96a9b25..639bec923e37b544368246ee072e58fd7154d3f0 100644
--- a/src/cell.c
+++ b/src/cell.c
@@ -3275,12 +3275,14 @@ int cell_unskip_hydro_tasks(struct cell *c, struct scheduler *s) {
 
         if (with_limiter) scheduler_activate(s, ci->mpi.limiter.recv);
         if (with_limiter)
-          scheduler_activate_send(s, cj->mpi.limiter.send, ci->nodeID);
+          scheduler_activate_send(s, cj->mpi.limiter.send, task_subtype_limiter,
+                                  ci->nodeID);
 
         /* Is the foreign cell active and will need stuff from us? */
         if (ci_active) {
 
-          scheduler_activate_send(s, cj->mpi.hydro.send_xv, ci_nodeID);
+          scheduler_activate_send(s, cj->mpi.hydro.send_xv, task_subtype_xv,
+                                  ci_nodeID);
 
           /* Drift the cell which will be sent; note that not all sent
              particles will be drifted, only those that are needed. */
@@ -3289,17 +3291,20 @@ int cell_unskip_hydro_tasks(struct cell *c, struct scheduler *s) {
 
           /* If the local cell is also active, more stuff will be needed. */
           if (cj_active) {
-            scheduler_activate_send(s, cj->mpi.hydro.send_rho, ci_nodeID);
+            scheduler_activate_send(s, cj->mpi.hydro.send_rho, task_subtype_rho,
+                                    ci_nodeID);
 
 #ifdef EXTRA_HYDRO_LOOP
-            scheduler_activate_send(s, cj->mpi.hydro.send_gradient, ci_nodeID);
+            scheduler_activate_send(s, cj->mpi.hydro.send_gradient,
+                                    task_subtype_gradient, ci_nodeID);
 #endif
           }
         }
 
         /* If the local cell is active, send its ti_end values. */
         if (cj_active || with_limiter)
-          scheduler_activate_send(s, cj->mpi.hydro.send_ti, ci_nodeID);
+          scheduler_activate_send(s, cj->mpi.hydro.send_ti,
+                                  task_subtype_tend_part, ci_nodeID);
 
       } else if (cj_nodeID != nodeID) {
 
@@ -3321,12 +3326,14 @@ int cell_unskip_hydro_tasks(struct cell *c, struct scheduler *s) {
 
         if (with_limiter) scheduler_activate(s, cj->mpi.limiter.recv);
         if (with_limiter)
-          scheduler_activate_send(s, ci->mpi.limiter.send, cj->nodeID);
+          scheduler_activate_send(s, ci->mpi.limiter.send, task_subtype_limiter,
+                                  cj->nodeID);
 
         /* Is the foreign cell active and will need stuff from us? */
         if (cj_active) {
 
-          scheduler_activate_send(s, ci->mpi.hydro.send_xv, cj_nodeID);
+          scheduler_activate_send(s, ci->mpi.hydro.send_xv, task_subtype_xv,
+                                  cj_nodeID);
 
           /* Drift the cell which will be sent; note that not all sent
              particles will be drifted, only those that are needed. */
@@ -3336,17 +3343,20 @@ int cell_unskip_hydro_tasks(struct cell *c, struct scheduler *s) {
           /* If the local cell is also active, more stuff will be needed. */
           if (ci_active) {
 
-            scheduler_activate_send(s, ci->mpi.hydro.send_rho, cj_nodeID);
+            scheduler_activate_send(s, ci->mpi.hydro.send_rho, task_subtype_rho,
+                                    cj_nodeID);
 
 #ifdef EXTRA_HYDRO_LOOP
-            scheduler_activate_send(s, ci->mpi.hydro.send_gradient, cj_nodeID);
+            scheduler_activate_send(s, ci->mpi.hydro.send_gradient,
+                                    task_subtype_gradient, cj_nodeID);
 #endif
           }
         }
 
         /* If the local cell is active, send its ti_end values. */
         if (ci_active || with_limiter)
-          scheduler_activate_send(s, ci->mpi.hydro.send_ti, cj_nodeID);
+          scheduler_activate_send(s, ci->mpi.hydro.send_ti,
+                                  task_subtype_tend_part, cj_nodeID);
       }
 #endif
     }
@@ -3449,7 +3459,8 @@ int cell_unskip_gravity_tasks(struct cell *c, struct scheduler *s) {
         /* Is the foreign cell active and will need stuff from us? */
         if (ci_active) {
 
-          scheduler_activate_send(s, cj->mpi.grav.send, ci_nodeID);
+          scheduler_activate_send(s, cj->mpi.grav.send, task_subtype_gpart,
+                                  ci_nodeID);
 
           /* Drift the cell which will be sent at the level at which it is
              sent, i.e. drift the cell specified in the send task (l->t)
@@ -3459,7 +3470,8 @@ int cell_unskip_gravity_tasks(struct cell *c, struct scheduler *s) {
 
         /* If the local cell is active, send its ti_end values. */
         if (cj_active)
-          scheduler_activate_send(s, cj->mpi.grav.send_ti, ci_nodeID);
+          scheduler_activate_send(s, cj->mpi.grav.send_ti,
+                                  task_subtype_tend_gpart, ci_nodeID);
 
       } else if (cj_nodeID != nodeID) {
 
@@ -3472,7 +3484,8 @@ int cell_unskip_gravity_tasks(struct cell *c, struct scheduler *s) {
         /* Is the foreign cell active and will need stuff from us? */
         if (cj_active) {
 
-          scheduler_activate_send(s, ci->mpi.grav.send, cj_nodeID);
+          scheduler_activate_send(s, ci->mpi.grav.send, task_subtype_gpart,
+                                  cj_nodeID);
 
           /* Drift the cell which will be sent at the level at which it is
              sent, i.e. drift the cell specified in the send task (l->t)
@@ -3482,7 +3495,8 @@ int cell_unskip_gravity_tasks(struct cell *c, struct scheduler *s) {
 
         /* If the local cell is active, send its ti_end values. */
         if (ci_active)
-          scheduler_activate_send(s, ci->mpi.grav.send_ti, cj_nodeID);
+          scheduler_activate_send(s, ci->mpi.grav.send_ti,
+                                  task_subtype_tend_gpart, cj_nodeID);
       }
 #endif
     }
@@ -3650,11 +3664,13 @@ int cell_unskip_stars_tasks(struct cell *c, struct scheduler *s) {
           scheduler_activate(s, ci->mpi.hydro.recv_rho);
 
           /* If the local cell is active, more stuff will be needed. */
-          scheduler_activate_send(s, cj->mpi.stars.send, ci_nodeID);
+          scheduler_activate_send(s, cj->mpi.stars.send, task_subtype_spart,
+                                  ci_nodeID);
           cell_activate_drift_spart(cj, s);
 
           /* If the local cell is active, send its ti_end values. */
-          scheduler_activate_send(s, cj->mpi.stars.send_ti, ci_nodeID);
+          scheduler_activate_send(s, cj->mpi.stars.send_ti,
+                                  task_subtype_tend_spart, ci_nodeID);
         }
 
         if (ci_active) {
@@ -3664,8 +3680,10 @@ int cell_unskip_stars_tasks(struct cell *c, struct scheduler *s) {
           scheduler_activate(s, ci->mpi.stars.recv_ti);
 
           /* Is the foreign cell active and will need stuff from us? */
-          scheduler_activate_send(s, cj->mpi.hydro.send_xv, ci_nodeID);
-          scheduler_activate_send(s, cj->mpi.hydro.send_rho, ci_nodeID);
+          scheduler_activate_send(s, cj->mpi.hydro.send_xv, task_subtype_xv,
+                                  ci_nodeID);
+          scheduler_activate_send(s, cj->mpi.hydro.send_rho, task_subtype_rho,
+                                  ci_nodeID);
 
           /* Drift the cell which will be sent; note that not all sent
              particles will be drifted, only those that are needed. */
@@ -3680,11 +3698,13 @@ int cell_unskip_stars_tasks(struct cell *c, struct scheduler *s) {
           scheduler_activate(s, cj->mpi.hydro.recv_rho);
 
           /* If the local cell is active, more stuff will be needed. */
-          scheduler_activate_send(s, ci->mpi.stars.send, cj_nodeID);
+          scheduler_activate_send(s, ci->mpi.stars.send, task_subtype_spart,
+                                  cj_nodeID);
           cell_activate_drift_spart(ci, s);
 
           /* If the local cell is active, send its ti_end values. */
-          scheduler_activate_send(s, ci->mpi.stars.send_ti, cj_nodeID);
+          scheduler_activate_send(s, ci->mpi.stars.send_ti,
+                                  task_subtype_tend_spart, cj_nodeID);
         }
 
         if (cj_active) {
@@ -3694,8 +3714,10 @@ int cell_unskip_stars_tasks(struct cell *c, struct scheduler *s) {
           scheduler_activate(s, cj->mpi.stars.recv_ti);
 
           /* Is the foreign cell active and will need stuff from us? */
-          scheduler_activate_send(s, ci->mpi.hydro.send_xv, cj_nodeID);
-          scheduler_activate_send(s, ci->mpi.hydro.send_rho, cj_nodeID);
+          scheduler_activate_send(s, ci->mpi.hydro.send_xv, task_subtype_xv,
+                                  cj_nodeID);
+          scheduler_activate_send(s, ci->mpi.hydro.send_rho, task_subtype_rho,
+                                  cj_nodeID);
 
           /* Drift the cell which will be sent; note that not all sent
              particles will be drifted, only those that are needed. */
diff --git a/src/cell.h b/src/cell.h
index 2881614981199ecdec99a2255ee09142cf7eccab..0405b39b7d3aeca226cbef3b983cf4778e5619c3 100644
--- a/src/cell.h
+++ b/src/cell.h
@@ -586,7 +586,10 @@ struct cell {
           /* Task receiving data (time-step). */
           struct task *recv_ti;
         };
-        struct {
+
+        // Using a union for now to make these all the same linked list. once
+        // this works, I'll replace the names.
+        union {
           /* Linked list for sending hydro data (positions). */
           struct link *send_xv;
 
@@ -604,35 +607,42 @@ struct cell {
     } hydro;
 
     struct {
-    union{ struct{
-      /* Task receiving gpart data. */
-      struct task *recv;
+      union {
+        struct {
+          /* Task receiving gpart data. */
+          struct task *recv;
 
-      /* Task receiving data (time-step). */
-      struct task *recv_ti;
-}; struct{
-      /* Linked list for sending gpart data. */
-      struct link *send;
+          /* Task receiving data (time-step). */
+          struct task *recv_ti;
+        };
+        struct {
+          /* Linked list for sending gpart data. */
+          struct link *send;
 
-      /* Linked list for sending data (time-step). */
-      struct link *send_ti;};};
+          /* Linked list for sending data (time-step). */
+          struct link *send_ti;
+        };
+      };
 
     } grav;
 
     struct {
-    union{ struct{
-      /* Task receiving spart data. */
-      struct task *recv;
+      union {
+        struct {
+          /* Task receiving spart data. */
+          struct task *recv;
 
-      /* Task receiving data (time-step). */
-      struct task *recv_ti;
-}; struct{
-      /* Linked list for sending spart data. */
-      struct link *send;
+          /* Task receiving data (time-step). */
+          struct task *recv_ti;
+        };
+        struct {
+          /* Linked list for sending spart data. */
+          struct link *send;
 
-      /* Linked list for sending data (time-step). */
-      struct link *send_ti;
-};};
+          /* Linked list for sending data (time-step). */
+          struct link *send_ti;
+        };
+      };
     } stars;
 
     union {
diff --git a/src/engine_marktasks.c b/src/engine_marktasks.c
index 114841b015c680973b5c3007cf4c03048cd861dc..5f3280053a34483dc879bc212fc0c6c138f13abb 100644
--- a/src/engine_marktasks.c
+++ b/src/engine_marktasks.c
@@ -376,8 +376,8 @@ void engine_marktasks_mapper(void *map_data, int num_elements,
 
           /* Is the foreign cell active and will need stuff from us? */
           if (ci_active_hydro) {
-            struct link *l =
-                scheduler_activate_send(s, cj->mpi.hydro.send_xv, ci_nodeID);
+            struct link *l = scheduler_activate_send(
+                s, cj->mpi.hydro.send_xv, task_subtype_xv, ci_nodeID);
 
             /* Drift the cell which will be sent at the level at which it is
                sent, i.e. drift the cell specified in the send task (l->t)
@@ -386,18 +386,20 @@ void engine_marktasks_mapper(void *map_data, int num_elements,
 
             /* If the local cell is also active, more stuff will be needed. */
             if (cj_active_hydro) {
-              scheduler_activate_send(s, cj->mpi.hydro.send_rho, ci_nodeID);
+              scheduler_activate_send(s, cj->mpi.hydro.send_rho,
+                                      task_subtype_rho, ci_nodeID);
 
 #ifdef EXTRA_HYDRO_LOOP
               scheduler_activate_send(s, cj->mpi.hydro.send_gradient,
-                                      ci_nodeID);
+                                      task_subtype_gradient, ci_nodeID);
 #endif
             }
           }
 
           /* If the local cell is active, send its ti_end values. */
           if (cj_active_hydro)
-            scheduler_activate_send(s, cj->mpi.hydro.send_ti, ci_nodeID);
+            scheduler_activate_send(s, cj->mpi.hydro.send_ti,
+                                    task_subtype_tend_part, ci_nodeID);
 
         } else if (cj_nodeID != nodeID) {
 
@@ -419,8 +421,8 @@ void engine_marktasks_mapper(void *map_data, int num_elements,
           /* Is the foreign cell active and will need stuff from us? */
           if (cj_active_hydro) {
 
-            struct link *l =
-                scheduler_activate_send(s, ci->mpi.hydro.send_xv, cj_nodeID);
+            struct link *l = scheduler_activate_send(
+                s, ci->mpi.hydro.send_xv, task_subtype_xv, cj_nodeID);
 
             /* Drift the cell which will be sent at the level at which it is
                sent, i.e. drift the cell specified in the send task (l->t)
@@ -430,18 +432,20 @@ void engine_marktasks_mapper(void *map_data, int num_elements,
             /* If the local cell is also active, more stuff will be needed. */
             if (ci_active_hydro) {
 
-              scheduler_activate_send(s, ci->mpi.hydro.send_rho, cj_nodeID);
+              scheduler_activate_send(s, ci->mpi.hydro.send_rho,
+                                      task_subtype_rho, cj_nodeID);
 
 #ifdef EXTRA_HYDRO_LOOP
               scheduler_activate_send(s, ci->mpi.hydro.send_gradient,
-                                      cj_nodeID);
+                                      task_subtype_gradient, cj_nodeID);
 #endif
             }
           }
 
           /* If the local cell is active, send its ti_end values. */
           if (ci_active_hydro)
-            scheduler_activate_send(s, ci->mpi.hydro.send_ti, cj_nodeID);
+            scheduler_activate_send(s, ci->mpi.hydro.send_ti,
+                                    task_subtype_tend_part, cj_nodeID);
         }
 #endif
       }
@@ -462,11 +466,13 @@ void engine_marktasks_mapper(void *map_data, int num_elements,
             scheduler_activate(s, ci->mpi.hydro.recv_rho);
 
             /* If the local cell is active, more stuff will be needed. */
-            scheduler_activate_send(s, cj->mpi.stars.send, ci_nodeID);
+            scheduler_activate_send(s, cj->mpi.stars.send, task_subtype_spart,
+                                    ci_nodeID);
             cell_activate_drift_spart(cj, s);
 
             /* If the local cell is active, send its ti_end values. */
-            scheduler_activate_send(s, cj->mpi.stars.send_ti, ci_nodeID);
+            scheduler_activate_send(s, cj->mpi.stars.send_ti,
+                                    task_subtype_tend_spart, ci_nodeID);
           }
 
           if (ci_active_stars) {
@@ -476,8 +482,10 @@ void engine_marktasks_mapper(void *map_data, int num_elements,
             scheduler_activate(s, ci->mpi.stars.recv_ti);
 
             /* Is the foreign cell active and will need stuff from us? */
-            scheduler_activate_send(s, cj->mpi.hydro.send_xv, ci_nodeID);
-            scheduler_activate_send(s, cj->mpi.hydro.send_rho, ci_nodeID);
+            scheduler_activate_send(s, cj->mpi.hydro.send_xv, task_subtype_xv,
+                                    ci_nodeID);
+            scheduler_activate_send(s, cj->mpi.hydro.send_rho, task_subtype_rho,
+                                    ci_nodeID);
 
             /* Drift the cell which will be sent; note that not all sent
                particles will be drifted, only those that are needed. */
@@ -492,11 +500,13 @@ void engine_marktasks_mapper(void *map_data, int num_elements,
             scheduler_activate(s, cj->mpi.hydro.recv_rho);
 
             /* If the local cell is active, more stuff will be needed. */
-            scheduler_activate_send(s, ci->mpi.stars.send, cj_nodeID);
+            scheduler_activate_send(s, ci->mpi.stars.send, task_subtype_spart,
+                                    cj_nodeID);
             cell_activate_drift_spart(ci, s);
 
             /* If the local cell is active, send its ti_end values. */
-            scheduler_activate_send(s, ci->mpi.stars.send_ti, cj_nodeID);
+            scheduler_activate_send(s, ci->mpi.stars.send_ti,
+                                    task_subtype_tend_spart, cj_nodeID);
           }
 
           if (cj_active_stars) {
@@ -506,8 +516,10 @@ void engine_marktasks_mapper(void *map_data, int num_elements,
             scheduler_activate(s, cj->mpi.stars.recv_ti);
 
             /* Is the foreign cell active and will need stuff from us? */
-            scheduler_activate_send(s, ci->mpi.hydro.send_xv, cj_nodeID);
-            scheduler_activate_send(s, ci->mpi.hydro.send_rho, cj_nodeID);
+            scheduler_activate_send(s, ci->mpi.hydro.send_xv, task_subtype_xv,
+                                    cj_nodeID);
+            scheduler_activate_send(s, ci->mpi.hydro.send_rho, task_subtype_rho,
+                                    cj_nodeID);
 
             /* Drift the cell which will be sent; note that not all sent
                particles will be drifted, only those that are needed. */
@@ -533,8 +545,8 @@ void engine_marktasks_mapper(void *map_data, int num_elements,
           /* Is the foreign cell active and will need stuff from us? */
           if (ci_active_gravity) {
 
-            struct link *l =
-                scheduler_activate_send(s, cj->mpi.grav.send, ci_nodeID);
+            struct link *l = scheduler_activate_send(
+                s, cj->mpi.grav.send, task_subtype_gpart, ci_nodeID);
 
             /* Drift the cell which will be sent at the level at which it is
                sent, i.e. drift the cell specified in the send task (l->t)
@@ -544,7 +556,8 @@ void engine_marktasks_mapper(void *map_data, int num_elements,
 
           /* If the local cell is active, send its ti_end values. */
           if (cj_active_gravity)
-            scheduler_activate_send(s, cj->mpi.grav.send_ti, ci_nodeID);
+            scheduler_activate_send(s, cj->mpi.grav.send_ti,
+                                    task_subtype_tend_gpart, ci_nodeID);
 
         } else if (cj_nodeID != nodeID) {
 
@@ -557,8 +570,8 @@ void engine_marktasks_mapper(void *map_data, int num_elements,
           /* Is the foreign cell active and will need stuff from us? */
           if (cj_active_gravity) {
 
-            struct link *l =
-                scheduler_activate_send(s, ci->mpi.grav.send, cj_nodeID);
+            struct link *l = scheduler_activate_send(
+                s, ci->mpi.grav.send, task_subtype_gpart, cj_nodeID);
 
             /* Drift the cell which will be sent at the level at which it is
                sent, i.e. drift the cell specified in the send task (l->t)
@@ -568,7 +581,8 @@ void engine_marktasks_mapper(void *map_data, int num_elements,
 
           /* If the local cell is active, send its ti_end values. */
           if (ci_active_gravity)
-            scheduler_activate_send(s, ci->mpi.grav.send_ti, cj_nodeID);
+            scheduler_activate_send(s, ci->mpi.grav.send_ti,
+                                    task_subtype_tend_gpart, cj_nodeID);
         }
 #endif
       }
diff --git a/src/scheduler.h b/src/scheduler.h
index 3fb1c2e43bddd73a08edd40c9c2969ea20ee6d39..e4c03b831efbc1e8ab6eb1c9746c787da0b11468 100644
--- a/src/scheduler.h
+++ b/src/scheduler.h
@@ -56,7 +56,6 @@
 
 /* Data of a scheduler. */
 struct scheduler {
-
   /* Scheduler flags. */
   unsigned int flags;
 
@@ -120,7 +119,6 @@ struct scheduler {
  */
 __attribute__((always_inline)) INLINE static void scheduler_activate(
     struct scheduler *s, struct task *t) {
-
   if (atomic_cas(&t->skip, 1, 0)) {
     t->wait = 0;
     int ind = atomic_inc(&s->active_count);
@@ -134,15 +132,18 @@ __attribute__((always_inline)) INLINE static void scheduler_activate(
  * @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.
  * @param nodeID The nodeID of the foreign cell.
  *
  * @return The #link to the MPI send task.
  */
 __attribute__((always_inline)) INLINE static struct link *
-scheduler_activate_send(struct scheduler *s, struct link *link, int nodeID) {
-
+scheduler_activate_send(struct scheduler *s, struct link *link,
+                        enum task_subtypes subtype, int nodeID) {
   struct link *l = NULL;
-  for (l = link; l != NULL && l->t->cj->nodeID != nodeID; l = l->next)
+  for (l = link;
+       l != NULL && !(l->t->cj->nodeID == nodeID && l->t->subtype == subtype);
+       l = l->next)
     ;
   if (l == NULL) {
     error("Missing link to send task.");