diff --git a/src/cell.h b/src/cell.h
index 59780697f42bce4b1fb778d7fcdf471de9cb2b27..7fda5fb40c69e1bc83a367265a0fbe9afb9ff266 100644
--- a/src/cell.h
+++ b/src/cell.h
@@ -670,6 +670,73 @@ int cell_can_use_pair_mm(const struct cell *ci, const struct cell *cj,
 int cell_can_use_pair_mm_rebuild(const struct cell *ci, const struct cell *cj,
                                  const struct engine *e, const struct space *s);
 
+/**
+ * @brief Compute the sqaure of the minimal distance between any two points in two cells of the same size
+ *
+ * @param ci The first #cell.
+ * @param cj The second #cell.
+ * @param periodic Are we using periodic BCs?
+ * @param dim The dimensions of the simulation volume
+ */
+__attribute__((always_inline)) INLINE static double 
+cell_min_dist2_same_size(const struct cell *restrict ci, const struct cell *restrict cj, const int periodic,
+			 const double dim[3]) {
+
+#ifdef SWIFT_DEBUG_CHECKS
+  if (ci->width[0] != cj->width[0])
+    error("Cells of different size!");
+  if (ci->width[1] != cj->width[1])
+    error("Cells of different size!");
+  if (ci->width[2] != cj->width[2])
+    error("Cells of different size!");
+#endif
+
+  const double cix_min = ci->loc[0];  
+  const double ciy_min = ci->loc[1];  
+  const double ciz_min = ci->loc[2];  
+  const double cjx_min = cj->loc[0];  
+  const double cjy_min = cj->loc[1];  
+  const double cjz_min = cj->loc[2];  
+  
+  const double cix_max = ci->loc[0] + ci->width[0];  
+  const double ciy_max = ci->loc[1] + ci->width[1];  
+  const double ciz_max = ci->loc[2] + ci->width[2];  
+  const double cjx_max = cj->loc[0] + cj->width[0];  
+  const double cjy_max = cj->loc[1] + cj->width[1];  
+  const double cjz_max = cj->loc[2] + cj->width[2];
+
+  if (periodic) {
+
+    const double dx = min4(fabs(nearest(cix_min - cjx_min, dim[0])),
+			   fabs(nearest(cix_min - cjx_max, dim[0])),
+			   fabs(nearest(cix_max - cjx_min, dim[0])),
+			   fabs(nearest(cix_max - cjx_max, dim[0])));
+    
+    const double dy = min4(fabs(nearest(ciy_min - cjy_min, dim[1])),
+			   fabs(nearest(ciy_min - cjy_max, dim[1])),
+			   fabs(nearest(ciy_max - cjy_min, dim[1])),
+			   fabs(nearest(ciy_max - cjy_max, dim[1])));
+    
+    const double dz = min4(fabs(nearest(ciz_min - cjz_min, dim[2])),
+			   fabs(nearest(ciz_min - cjz_max, dim[2])),
+			   fabs(nearest(ciz_max - cjz_min, dim[2])),
+			   fabs(nearest(ciz_max - cjz_max, dim[2])));
+    
+    return dx * dx + dy * dy + dz * dz;
+
+  } else {
+
+    const double dx = min(fabs(cix_max - cjx_min),
+			  fabs(cix_min - cjx_max));
+    const double dy = min(fabs(ciy_max - cjy_min),
+			  fabs(ciy_min - cjy_max));
+    const double dz = min(fabs(ciz_max - cjz_min),
+			  fabs(ciz_min - cjz_max));
+
+    return dx * dx + dy * dy + dz * dz;
+  }
+}
+
 /* Inlined functions (for speed). */
 
 /**
diff --git a/src/engine.c b/src/engine.c
index 5fddc4a319898bbfb3bc5a3dd53d85f1c4d9db7f..c125b09cd9b2a32a8192bfa833ad1fbd70f4579d 100644
--- a/src/engine.c
+++ b/src/engine.c
@@ -3612,15 +3612,17 @@ void engine_makeproxies(struct engine *e) {
   const int with_gravity = (e->policy & engine_policy_self_gravity);
   const double theta_crit_inv = e->gravity_properties->theta_crit_inv;
   const double theta_crit2 = e->gravity_properties->theta_crit2;
-  const double max_distance = e->mesh->r_cut_max;
+  const double max_mesh_dist = e->mesh->r_cut_max;
+  const double max_mesh_dist2 = max_mesh_dist * max_mesh_dist;
 
   /* Maximal distance between CoMs and any particle in the cell */
   const double r_max2 = cell_width[0] * cell_width[0] +
                         cell_width[1] * cell_width[1] +
                         cell_width[2] * cell_width[2];
-  const double r_max = sqrt(r_max2);
 
-  message("PROXIES: r_max= %e max_distance= %e", r_max, max_distance);
+  /* Maximal distance assuming the CoM can have moved by from the centre by 
+     engine_max_proxy_centre_frac (default: 20%) of the cell */
+  const double r_max = sqrt(r_max2) * 0.5 * (1. + 2. * engine_max_proxy_centre_frac);
 
   /* Prepare the proxies and the proxy index. */
   if (e->proxy_ind == NULL)
@@ -3673,11 +3675,7 @@ void engine_makeproxies(struct engine *e) {
 	
         /* Get the cell ID. */
         const int cid = cell_getid(cdim, i, j, k);
-	
-        /* and it's location */
-        const double loc_i[3] = {cells[cid].loc[0], cells[cid].loc[1],
-                                 cells[cid].loc[2]};
-	
+		
         /* Loop over all its neighbours neighbours in range. */
         for (int ii = -delta_m; ii <= delta_p; ii++) {
           int iii = i + ii;
@@ -3738,44 +3736,20 @@ void engine_makeproxies(struct engine *e) {
                    for an M2L interaction and hence require a proxy as this pair
                    of cells cannot rely on just an M2L calculation. */
 
-                const double loc_j[3] = {cells[cjd].loc[0], cells[cjd].loc[1],
-                                         cells[cjd].loc[2]};
-
-                /* Start with the distance between the cell centres. */
-                double dx = loc_i[0] - loc_j[0];
-                double dy = loc_i[1] - loc_j[1];
-                double dz = loc_i[2] - loc_j[2];
-
-                /* Apply BC */
-                if (periodic) {
-                  dx = nearest(dx, dim[0]);
-                  dy = nearest(dy, dim[1]);
-                  dz = nearest(dz, dim[2]);
-                }
-
-                /* Add to it for the case where the future CoMs are in the
-                 * corners */
-                dx += cell_width[0];
-                dy += cell_width[1];
-                dz += cell_width[2];
-
-                /* This is a crazy upper-bound but the best we can do */
-                const double r2 = dx * dx + dy * dy + dz * dz;
-
-                /* Minimal distance between any pair of particles */
-                const double min_radius = sqrt(r2) - 2. * r_max;
+		/* Minimal distance between any two points in the cells */
+		const double min_dist2 = cell_min_dist2_same_size(&cells[cid], &cells[cjd], periodic, dim);
 
                 /* Are we beyond the distance where the truncated forces are 0
                  * but not too far such that M2L can be used? */
                 if (periodic) {
 
-                  if ((min_radius < max_distance) &&
-                      (!gravity_M2L_accept(r_max, r_max, theta_crit2, r2)))
+                  if ((min_dist2 < max_mesh_dist2) &&
+                      (!gravity_M2L_accept(r_max, r_max, theta_crit2, min_dist2)))
                     proxy_type |= (int)proxy_cell_type_gravity;
 
                 } else {
 
-                  if (!gravity_M2L_accept(r_max, r_max, theta_crit2, r2))
+                  if (!gravity_M2L_accept(r_max, r_max, theta_crit2, min_dist2))
                     proxy_type |= (int)proxy_cell_type_gravity;
                 }
               }
diff --git a/src/engine.h b/src/engine.h
index 50eef4b314da4c294a86e59e29542859f7f402f2..81e1b533b43f6c26214d30fc7c19976f00e3ea2f 100644
--- a/src/engine.h
+++ b/src/engine.h
@@ -98,6 +98,7 @@ enum engine_step_properties {
 #define engine_maxproxies 64
 #define engine_tasksreweight 1
 #define engine_parts_size_grow 1.05
+#define engine_max_proxy_centre_frac 0.25
 #define engine_redistribute_alloc_margin 1.2
 #define engine_default_energy_file_name "energy"
 #define engine_default_timesteps_file_name "timesteps"
diff --git a/src/engine_maketasks.c b/src/engine_maketasks.c
index c831b31ed6bcf3c237f945b1f65aa4100a6f2eaa..5daa1d167827dee5995f3e8218c1ac914be961e3 100644
--- a/src/engine_maketasks.c
+++ b/src/engine_maketasks.c
@@ -890,11 +890,13 @@ void engine_make_self_gravity_tasks_mapper(void *map_data, int num_elements,
 	      const struct proxy *p = &e->proxies[proxy_id];
 	      
 	      /* Check whether the cell exists in the proxy */
-	      int n = 0;
-	      for (n = 0; n < p->nr_cells_in; n++) 
-		if(p->cells_in[n] == cj)
+	      int n = 0, err = 1;
+	      for (; n < p->nr_cells_in; n++) 
+		if(p->cells_in[n] == cj) {
+		  err = 0;
 		  break;
-	      if(n == p->nr_cells_in)
+		}
+	      if(err)
 		error("Cell %d not found in the proxy but trying to construct grav task!",
 		      cjd);
 	    }
@@ -908,11 +910,13 @@ void engine_make_self_gravity_tasks_mapper(void *map_data, int num_elements,
 	      const struct proxy *p = &e->proxies[proxy_id];
 	      
 	      /* Check whether the cell exists in the proxy */
-	      int n = 0;
-	      for (n = 0; n < p->nr_cells_in; n++) 
-		if(p->cells_in[n] == ci)
+	      int n = 0, err = 1;
+	      for (; n < p->nr_cells_in; n++) 
+		if(p->cells_in[n] == ci) {
+		  err = 0;
 		  break;
-	      if(n == p->nr_cells_in)
+		}
+	      if(err)
 		error("Cell %d not found in the proxy but trying to construct grav task!",
 		      cid);	  
 	    }
@@ -2059,6 +2063,13 @@ void engine_maketasks(struct engine *e) {
     message("Linking stars tasks took %.3f %s (including reweight).",
             clocks_from_ticks(getticks() - tic2), clocks_getunit());
 
+  if(e->nodeID == 0)
+    for(int i = 0; i < e->s->nr_cells; ++i) {
+      message("cid= %d num_grav_proxy= %d num_hydro_proxy= %d num_foreign_grav= %d num_foreign_hydro= %d",
+	      i, e->s->cells_top[i].num_grav_proxies, e->s->cells_top[i].num_hydro_proxies,
+	      e->s->cells_top[i].num_foreign_pair_grav, e->s->cells_top[i].num_foreign_pair_hydro);
+    }
+
 #ifdef WITH_MPI
   if (e->policy & engine_policy_feedback)
     error("Cannot run stellar feedback with MPI (yet).");