diff --git a/examples/analyse_tasks.py b/examples/analyse_tasks.py
index 48a00a63ea5da5cb80ebd6f10187cc613c1a5ed5..343814d58a89d5e15a1e12e7745f776b3a769184 100755
--- a/examples/analyse_tasks.py
+++ b/examples/analyse_tasks.py
@@ -52,8 +52,8 @@ infile = args.input
 
 #  Tasks and subtypes. Indexed as in tasks.h.
 TASKTYPES = ["none", "sort", "self", "pair", "sub_self", "sub_pair",
-             "init_grav", "init_grav_out", "ghost_in", "ghost", "ghost_out", "extra_ghost", "drift_part", "drift_gpart",
-             "end_force", "kick1", "kick2", "timestep", "send", "recv", "grav_long_range", "grav_mm", "grav_down_in", 
+             "init_grav", "init_grav_out", "ghost_in", "ghost", "ghost_out", "extra_ghost", "drift_part", "drift_gpart", "drift_gpart_out",
+             "end_force", "end_force_in", "kick1", "kick2", "timestep", "send", "recv", "grav_long_range", "grav_mm", "grav_down_in", 
              "grav_down", "grav_mesh", "cooling", "star_formation", "sourceterms",
              "stars_ghost_in", "stars_ghost",   "stars_ghost_out",
              "count"]
diff --git a/examples/plot_tasks.py b/examples/plot_tasks.py
index 76128ac66af21cd5f6d9a7ab0546ed813bde4536..588061cd497f180afec36caec4bcf59a5ee4cb54 100755
--- a/examples/plot_tasks.py
+++ b/examples/plot_tasks.py
@@ -110,8 +110,8 @@ pl.rcParams.update(PLOT_PARAMS)
 
 #  Tasks and subtypes. Indexed as in tasks.h.
 TASKTYPES = ["none", "sort", "self", "pair", "sub_self", "sub_pair",
-             "init_grav", "init_grav_out", "ghost_in", "ghost", "ghost_out", "extra_ghost", "drift_part", "drift_gpart",
-             "end_force", "kick1", "kick2", "timestep", "send", "recv", "grav_long_range", "grav_mm", "grav_down_in", 
+             "init_grav", "init_grav_out", "ghost_in", "ghost", "ghost_out", "extra_ghost", "drift_part", "drift_gpart", "drift_gpart_out",
+             "end_force", "end_force_in", "kick1", "kick2", "timestep", "send", "recv", "grav_long_range", "grav_mm", "grav_down_in", 
              "grav_down", "grav_mesh", "cooling", "star_formation", "sourceterms",
              "stars_ghost_in", "stars_ghost",   "stars_ghost_out",
              "count"]
diff --git a/src/cell.c b/src/cell.c
index 37b7be42f3aa04d79496d2913d30654af93ea45e..b869803f15a63d380dedbc0182e1100bb97f9bc2 100644
--- a/src/cell.c
+++ b/src/cell.c
@@ -1626,6 +1626,8 @@ void cell_activate_drift_gpart(struct cell *c, struct scheduler *s) {
   /* Mark this cell for drifting. */
   c->grav.do_drift = 1;
 
+  if (c->grav.drift_out != NULL) scheduler_activate(s, c->grav.drift_out);
+
   /* Set the do_grav_sub_drifts all the way up and activate the super drift
      if this has not yet been done. */
   if (c == c->grav.super) {
@@ -1639,6 +1641,11 @@ void cell_activate_drift_gpart(struct cell *c, struct scheduler *s) {
          parent != NULL && !parent->grav.do_sub_drift;
          parent = parent->parent) {
       parent->grav.do_sub_drift = 1;
+
+      if (parent->grav.drift_out) {
+        scheduler_activate(s, parent->grav.drift_out);
+      }
+
       if (parent == c->grav.super) {
 #ifdef SWIFT_DEBUG_CHECKS
         if (parent->grav.drift == NULL)
@@ -2760,6 +2767,7 @@ int cell_unskip_hydro_tasks(struct cell *c, struct scheduler *s) {
     if (c->kick2 != NULL) scheduler_activate(s, c->kick2);
     if (c->timestep != NULL) scheduler_activate(s, c->timestep);
     if (c->end_force != NULL) scheduler_activate(s, c->end_force);
+    if (c->end_force_in != NULL) scheduler_activate(s, c->end_force_in);
     if (c->hydro.cooling != NULL) scheduler_activate(s, c->hydro.cooling);
     if (c->hydro.star_formation != NULL)
       scheduler_activate(s, c->hydro.star_formation);
@@ -2909,16 +2917,19 @@ int cell_unskip_gravity_tasks(struct cell *c, struct scheduler *s) {
     if (c->kick2 != NULL) scheduler_activate(s, c->kick2);
     if (c->timestep != NULL) scheduler_activate(s, c->timestep);
     if (c->end_force != NULL) scheduler_activate(s, c->end_force);
-    if ((e->policy & engine_policy_cooling) && c->hydro.cooling != NULL)
-      scheduler_activate(s, c->hydro.cooling);
-    if ((e->policy & engine_policy_star_formation) &&
-        c->hydro.star_formation != NULL)
-      scheduler_activate(s, c->hydro.star_formation);
+    if (c->end_force_in != NULL) scheduler_activate(s, c->end_force_in);
     if (c->grav.down != NULL) scheduler_activate(s, c->grav.down);
     if (c->grav.down_in != NULL) scheduler_activate(s, c->grav.down_in);
     if (c->grav.mesh != NULL) scheduler_activate(s, c->grav.mesh);
     if (c->grav.long_range != NULL) scheduler_activate(s, c->grav.long_range);
     if (c->logger != NULL) scheduler_activate(s, c->logger);
+
+    /* Subgrid tasks */
+    if ((e->policy & engine_policy_cooling) && c->hydro.cooling != NULL)
+      scheduler_activate(s, c->hydro.cooling);
+    if ((e->policy & engine_policy_star_formation) &&
+        c->hydro.star_formation != NULL)
+      scheduler_activate(s, c->hydro.star_formation);
   }
 
   return rebuild;
diff --git a/src/cell.h b/src/cell.h
index 6203c0ec5aef8db4c989949eeaf08d7dfe064094..575b764b9b2d85799a0e4e39f2e44c30b2ca02cb 100644
--- a/src/cell.h
+++ b/src/cell.h
@@ -404,6 +404,9 @@ struct cell {
     /*! The drift task for gparts */
     struct task *drift;
 
+    /*! Implicit task (going up- and down the tree) for the #gpart drifts */
+    struct task *drift_out;
+
     /*! Linked list of the tasks computing this cell's gravity forces. */
     struct link *grav;
 
@@ -538,6 +541,9 @@ struct cell {
   /*! The task to end the force calculation */
   struct task *end_force;
 
+  /*! Implicit task (going up- and down the tree) for the end force */
+  struct task *end_force_in;
+
   /*! The first kick task */
   struct task *kick1;
 
diff --git a/src/engine_maketasks.c b/src/engine_maketasks.c
index 270b1d3868ba90a5102d3760cdb1f91570abb9de..f971aa003eddb03db4c1b4ae55cd27c78cc493a0 100644
--- a/src/engine_maketasks.c
+++ b/src/engine_maketasks.c
@@ -169,7 +169,7 @@ void engine_addtasks_send_hydro(struct engine *e, struct cell *ci,
 
 #else
       /* The send_rho task should unlock the super_hydro-cell's kick task. */
-      scheduler_addunlock(s, t_rho, ci->super->end_force);
+      scheduler_addunlock(s, t_rho, ci->super->end_force_in);
 
       /* The send_rho task depends on the cell's ghost task. */
       scheduler_addunlock(s, ci->hydro.super->hydro.ghost_out, t_rho);
@@ -462,6 +462,11 @@ void engine_make_hierarchical_tasks_common(struct engine *e, struct cell *c) {
       c->end_force = scheduler_addtask(s, task_type_end_force,
                                        task_subtype_none, 0, 0, c, NULL);
 
+      /* Implicit task for the up pass */
+      c->end_force_in = scheduler_addtask(s, task_type_end_force_in,
+                                          task_subtype_none, 0, 1, c, NULL);
+
+      /* Subgrid tasks */
       if (is_with_cooling) {
 
         c->hydro.cooling = scheduler_addtask(s, task_type_cooling,
@@ -485,21 +490,35 @@ void engine_make_hierarchical_tasks_common(struct engine *e, struct cell *c) {
       } else {
         scheduler_addunlock(s, c->kick2, c->timestep);
       }
+
+      scheduler_addunlock(s, c->end_force_in, c->end_force);
       scheduler_addunlock(s, c->timestep, c->kick1);
 
 #if defined(WITH_LOGGER)
       scheduler_addunlock(s, c->kick1, c->logger);
 #endif
     }
+  }
 
-  } else { /* We are above the super-cell so need to go deeper */
+  /* We are below the super-cell but not below the maximal splitting depth */
+  else if ((c->super != NULL) &&
+           ((c->maxdepth - c->depth) >= space_subdepth_diff_grav)) {
 
-    /* Recurse. */
-    if (c->split)
-      for (int k = 0; k < 8; k++)
-        if (c->progeny[k] != NULL)
-          engine_make_hierarchical_tasks_common(e, c->progeny[k]);
+    /* Local tasks only... */
+    if (c->nodeID == e->nodeID) {
+
+      c->end_force_in = scheduler_addtask(s, task_type_end_force_in,
+                                          task_subtype_none, 0, 1, c, NULL);
+
+      scheduler_addunlock(s, c->end_force_in, c->parent->end_force_in);
+    }
   }
+
+  /* Recurse. */
+  if (c->split)
+    for (int k = 0; k < 8; k++)
+      if (c->progeny[k] != NULL)
+        engine_make_hierarchical_tasks_common(e, c->progeny[k]);
 }
 
 /**
@@ -544,6 +563,8 @@ void engine_make_hierarchical_tasks_gravity(struct engine *e, struct cell *c) {
                                          task_subtype_none, 0, 0, c, NULL);
 
         /* Implicit tasks for the up and down passes */
+        c->grav.drift_out = scheduler_addtask(s, task_type_drift_gpart_out,
+                                              task_subtype_none, 0, 1, c, NULL);
         c->grav.init_out = scheduler_addtask(s, task_type_init_grav_out,
                                              task_subtype_none, 0, 1, c, NULL);
         c->grav.down_in = scheduler_addtask(s, task_type_grav_down_in,
@@ -562,6 +583,7 @@ void engine_make_hierarchical_tasks_gravity(struct engine *e, struct cell *c) {
 
         /* Link in the implicit tasks */
         scheduler_addunlock(s, c->grav.init, c->grav.init_out);
+        scheduler_addunlock(s, c->grav.drift, c->grav.drift_out);
         scheduler_addunlock(s, c->grav.down_in, c->grav.down);
       }
     }
@@ -1129,7 +1151,7 @@ void engine_link_gravity_tasks(struct engine *e) {
 
       /* drift ---+-> gravity --> grav_down */
       /* init  --/    */
-      scheduler_addunlock(sched, ci->grav.super->grav.drift, t);
+      scheduler_addunlock(sched, ci->grav.super->grav.drift_out, t);
       scheduler_addunlock(sched, ci_parent->grav.init_out, t);
       scheduler_addunlock(sched, t, ci_parent->grav.down_in);
     }
@@ -1142,8 +1164,8 @@ void engine_link_gravity_tasks(struct engine *e) {
 #endif
 
       /* drift -----> gravity --> end_force */
-      scheduler_addunlock(sched, ci->grav.super->grav.drift, t);
-      scheduler_addunlock(sched, t, ci->super->end_force);
+      scheduler_addunlock(sched, ci->grav.super->grav.drift_out, t);
+      scheduler_addunlock(sched, t, ci->end_force_in);
     }
 
     /* Otherwise, pair interaction? */
@@ -1153,7 +1175,7 @@ void engine_link_gravity_tasks(struct engine *e) {
 
         /* drift ---+-> gravity --> grav_down */
         /* init  --/    */
-        scheduler_addunlock(sched, ci->grav.super->grav.drift, t);
+        scheduler_addunlock(sched, ci->grav.super->grav.drift_out, t);
         scheduler_addunlock(sched, ci_parent->grav.init_out, t);
         scheduler_addunlock(sched, t, ci_parent->grav.down_in);
       }
@@ -1162,7 +1184,7 @@ void engine_link_gravity_tasks(struct engine *e) {
         /* drift ---+-> gravity --> grav_down */
         /* init  --/    */
         if (ci->grav.super != cj->grav.super) /* Avoid double unlock */
-          scheduler_addunlock(sched, cj->grav.super->grav.drift, t);
+          scheduler_addunlock(sched, cj->grav.super->grav.drift_out, t);
 
         if (ci_parent != cj_parent) { /* Avoid double unlock */
           scheduler_addunlock(sched, cj_parent->grav.init_out, t);
@@ -1179,7 +1201,7 @@ void engine_link_gravity_tasks(struct engine *e) {
 #endif
       /* drift ---+-> gravity --> grav_down */
       /* init  --/    */
-      scheduler_addunlock(sched, ci->grav.super->grav.drift, t);
+      scheduler_addunlock(sched, ci->grav.super->grav.drift_out, t);
       scheduler_addunlock(sched, ci_parent->grav.init_out, t);
       scheduler_addunlock(sched, t, ci_parent->grav.down_in);
     }
@@ -1193,8 +1215,8 @@ void engine_link_gravity_tasks(struct engine *e) {
 #endif
 
       /* drift -----> gravity --> end_force */
-      scheduler_addunlock(sched, ci->grav.super->grav.drift, t);
-      scheduler_addunlock(sched, t, ci->super->end_force);
+      scheduler_addunlock(sched, ci->grav.super->grav.drift_out, t);
+      scheduler_addunlock(sched, t, ci->end_force_in);
     }
 
     /* Otherwise, sub-pair interaction? */
@@ -1204,7 +1226,7 @@ void engine_link_gravity_tasks(struct engine *e) {
 
         /* drift ---+-> gravity --> grav_down */
         /* init  --/    */
-        scheduler_addunlock(sched, ci->grav.super->grav.drift, t);
+        scheduler_addunlock(sched, ci->grav.super->grav.drift_out, t);
         scheduler_addunlock(sched, ci_parent->grav.init_out, t);
         scheduler_addunlock(sched, t, ci_parent->grav.down_in);
       }
@@ -1213,7 +1235,7 @@ void engine_link_gravity_tasks(struct engine *e) {
         /* drift ---+-> gravity --> grav_down */
         /* init  --/    */
         if (ci->grav.super != cj->grav.super) /* Avoid double unlock */
-          scheduler_addunlock(sched, cj->grav.super->grav.drift, t);
+          scheduler_addunlock(sched, cj->grav.super->grav.drift_out, t);
 
         if (ci_parent != cj_parent) { /* Avoid double unlock */
           scheduler_addunlock(sched, cj_parent->grav.init_out, t);
@@ -1349,7 +1371,7 @@ void engine_make_extra_hydroloop_tasks_mapper(void *map_data, int num_elements,
       /* Now, build all the dependencies for the hydro */
       engine_make_hydro_loops_dependencies(sched, t, t2, t3, t->ci,
                                            with_cooling);
-      scheduler_addunlock(sched, t3, t->ci->super->end_force);
+      scheduler_addunlock(sched, t3, t->ci->super->end_force_in);
 #else
 
       /* Start by constructing the task for the second hydro loop */
@@ -1361,7 +1383,7 @@ void engine_make_extra_hydroloop_tasks_mapper(void *map_data, int num_elements,
 
       /* Now, build all the dependencies for the hydro */
       engine_make_hydro_loops_dependencies(sched, t, t2, t->ci, with_cooling);
-      scheduler_addunlock(sched, t2, t->ci->super->end_force);
+      scheduler_addunlock(sched, t2, t->ci->end_force_in);
 #endif
     }
 
@@ -1396,14 +1418,14 @@ void engine_make_extra_hydroloop_tasks_mapper(void *map_data, int num_elements,
       if (t->ci->nodeID == nodeID) {
         engine_make_hydro_loops_dependencies(sched, t, t2, t3, t->ci,
                                              with_cooling);
-        scheduler_addunlock(sched, t3, t->ci->super->end_force);
+        scheduler_addunlock(sched, t3, t->ci->super->end_force_in);
       }
       if (t->cj->nodeID == nodeID) {
         if (t->ci->hydro.super != t->cj->hydro.super)
           engine_make_hydro_loops_dependencies(sched, t, t2, t3, t->cj,
                                                with_cooling);
         if (t->ci->super != t->cj->super)
-          scheduler_addunlock(sched, t3, t->cj->super->end_force);
+          scheduler_addunlock(sched, t3, t->cj->super->end_force_in);
       }
 
 #else
@@ -1420,14 +1442,14 @@ void engine_make_extra_hydroloop_tasks_mapper(void *map_data, int num_elements,
       /* that are local and are not descendant of the same super_hydro-cells */
       if (t->ci->nodeID == nodeID) {
         engine_make_hydro_loops_dependencies(sched, t, t2, t->ci, with_cooling);
-        scheduler_addunlock(sched, t2, t->ci->super->end_force);
+        scheduler_addunlock(sched, t2, t->ci->super->end_force_in);
       }
       if (t->cj->nodeID == nodeID) {
         if (t->ci->hydro.super != t->cj->hydro.super)
           engine_make_hydro_loops_dependencies(sched, t, t2, t->cj,
                                                with_cooling);
         if (t->ci->super != t->cj->super)
-          scheduler_addunlock(sched, t2, t->cj->super->end_force);
+          scheduler_addunlock(sched, t2, t->cj->super->end_force_in);
       }
 
 #endif
@@ -1461,7 +1483,7 @@ void engine_make_extra_hydroloop_tasks_mapper(void *map_data, int num_elements,
       if (t->ci->nodeID == nodeID) {
         engine_make_hydro_loops_dependencies(sched, t, t2, t3, t->ci,
                                              with_cooling);
-        scheduler_addunlock(sched, t3, t->ci->super->end_force);
+        scheduler_addunlock(sched, t3, t->ci->super->end_force_in);
       }
 
 #else
@@ -1477,7 +1499,7 @@ void engine_make_extra_hydroloop_tasks_mapper(void *map_data, int num_elements,
       /* that are local and are not descendant of the same super_hydro-cells */
       if (t->ci->nodeID == nodeID) {
         engine_make_hydro_loops_dependencies(sched, t, t2, t->ci, with_cooling);
-        scheduler_addunlock(sched, t2, t->ci->super->end_force);
+        scheduler_addunlock(sched, t2, t->ci->super->end_force_in);
       }
 #endif
     }
@@ -1517,14 +1539,14 @@ void engine_make_extra_hydroloop_tasks_mapper(void *map_data, int num_elements,
       if (t->ci->nodeID == nodeID) {
         engine_make_hydro_loops_dependencies(sched, t, t2, t3, t->ci,
                                              with_cooling);
-        scheduler_addunlock(sched, t3, t->ci->super->end_force);
+        scheduler_addunlock(sched, t3, t->ci->super->end_force_in);
       }
       if (t->cj->nodeID == nodeID) {
         if (t->ci->hydro.super != t->cj->hydro.super)
           engine_make_hydro_loops_dependencies(sched, t, t2, t3, t->cj,
                                                with_cooling);
         if (t->ci->super != t->cj->super)
-          scheduler_addunlock(sched, t3, t->cj->super->end_force);
+          scheduler_addunlock(sched, t3, t->cj->super->end_force_in);
       }
 
 #else
@@ -1541,14 +1563,14 @@ void engine_make_extra_hydroloop_tasks_mapper(void *map_data, int num_elements,
       /* that are local and are not descendant of the same super_hydro-cells */
       if (t->ci->nodeID == nodeID) {
         engine_make_hydro_loops_dependencies(sched, t, t2, t->ci, with_cooling);
-        scheduler_addunlock(sched, t2, t->ci->super->end_force);
+        scheduler_addunlock(sched, t2, t->ci->super->end_force_in);
       }
       if (t->cj->nodeID == nodeID) {
         if (t->ci->hydro.super != t->cj->hydro.super)
           engine_make_hydro_loops_dependencies(sched, t, t2, t->cj,
                                                with_cooling);
         if (t->ci->super != t->cj->super)
-          scheduler_addunlock(sched, t2, t->cj->super->end_force);
+          scheduler_addunlock(sched, t2, t->cj->super->end_force_in);
       }
 #endif
     }
@@ -1584,7 +1606,7 @@ void engine_link_stars_tasks_mapper(void *map_data, int num_elements,
       engine_make_stars_loops_dependencies(sched, t, t->ci);
       if (t->ci == t->ci->super)
         scheduler_addunlock(sched, t->ci->super->stars.ghost_out,
-                            t->ci->super->end_force);
+                            t->ci->super->end_force_in);
     }
 
     /* Otherwise, pair interaction? */
diff --git a/src/engine_marktasks.c b/src/engine_marktasks.c
index c891fb2ca7aa66538adbbb8e1fd694f3af6acf07..d3208de3e53328791030534b2d3dcc51941becea 100644
--- a/src/engine_marktasks.c
+++ b/src/engine_marktasks.c
@@ -443,7 +443,8 @@ void engine_marktasks_mapper(void *map_data, int num_elements,
     }
 
     /* End force ? */
-    else if (t_type == task_type_end_force) {
+    else if (t_type == task_type_end_force ||
+             t_type == task_type_end_force_in) {
 
       if (cell_is_active_hydro(t->ci, e) || cell_is_active_gravity(t->ci, e))
         scheduler_activate(s, t);
diff --git a/src/task.c b/src/task.c
index 996c5113bac9935f70a3aafafd58da965b13f5aa..6580bf4a6b5c0ecb4e0265e2d3927ac0b7000ae4 100644
--- a/src/task.c
+++ b/src/task.c
@@ -47,18 +47,40 @@
 #include "lock.h"
 
 /* Task type names. */
-const char *taskID_names[task_type_count] = {
-    "none",        "sort",           "self",
-    "pair",        "sub_self",       "sub_pair",
-    "init_grav",   "init_grav_out",  "ghost_in",
-    "ghost",       "ghost_out",      "extra_ghost",
-    "drift_part",  "drift_gpart",    "end_force",
-    "kick1",       "kick2",          "timestep",
-    "send",        "recv",           "grav_long_range",
-    "grav_mm",     "grav_down_in",   "grav_down",
-    "grav_mesh",   "cooling",        "star_formation",
-    "sourceterms", "logger",         "stars_ghost_in",
-    "stars_ghost", "stars_ghost_out"};
+const char *taskID_names[task_type_count] = {"none",
+                                             "sort",
+                                             "self",
+                                             "pair",
+                                             "sub_self",
+                                             "sub_pair",
+                                             "init_grav",
+                                             "init_grav_out",
+                                             "ghost_in",
+                                             "ghost",
+                                             "ghost_out",
+                                             "extra_ghost",
+                                             "drift_part",
+                                             "drift_gpart",
+                                             "drift_gpart_out",
+                                             "end_force",
+                                             "end_force_in",
+                                             "kick1",
+                                             "kick2",
+                                             "timestep",
+                                             "send",
+                                             "recv",
+                                             "grav_long_range",
+                                             "grav_mm",
+                                             "grav_down_in",
+                                             "grav_down",
+                                             "grav_mesh",
+                                             "cooling",
+                                             "star_formation",
+                                             "sourceterms",
+                                             "logger",
+                                             "stars_ghost_in",
+                                             "stars_ghost",
+                                             "stars_ghost_out"};
 
 /* Sub-task type names. */
 const char *subtaskID_names[task_subtype_count] = {
diff --git a/src/task.h b/src/task.h
index 9b3225fcf27b768059a2984847d20750d184f8d2..90016472cfd0c6b913b09ca6ab52e663e6b8bff8 100644
--- a/src/task.h
+++ b/src/task.h
@@ -53,7 +53,9 @@ enum task_types {
   task_type_extra_ghost,
   task_type_drift_part,
   task_type_drift_gpart,
+  task_type_drift_gpart_out, /* Implicit */
   task_type_end_force,
+  task_type_end_force_in, /* Implicit */
   task_type_kick1,
   task_type_kick2,
   task_type_timestep,