diff --git a/src/engine.c b/src/engine.c
index eacba39429871f2370378398a1e850926f643d44..94cee6ba9979f9d23b2372fd8c14780f030e9f8f 100644
--- a/src/engine.c
+++ b/src/engine.c
@@ -1868,6 +1868,10 @@ void engine_exchange_strays(struct engine *e, const size_t offset_parts,
 
   /* Put the parts into the corresponding proxies. */
   for (size_t k = 0; k < *Npart; k++) {
+
+    /* Ignore the particles we want to get rid of (inhibited, ...). */
+    if (ind_part[k] == -1) continue;
+
     /* Get the target node and proxy ID. */
     const int node_id = e->s->cells_top[ind_part[k]].nodeID;
     if (node_id < 0 || node_id >= e->nr_nodes)
@@ -1888,6 +1892,11 @@ void engine_exchange_strays(struct engine *e, const size_t offset_parts,
           -e->proxies[pid].nr_parts_out;
     }
 
+#ifdef SWIFT_DEBUG_CHECKS
+    if (s->parts[offset_parts + k].time_bin == time_bin_inhibited)
+      error("Attempting to exchange an inhibited particle");
+#endif
+
     /* Load the part and xpart into the proxy. */
     proxy_parts_load(&e->proxies[pid], &s->parts[offset_parts + k],
                      &s->xparts[offset_parts + k], 1);
@@ -1895,17 +1904,23 @@ void engine_exchange_strays(struct engine *e, const size_t offset_parts,
 
   /* Put the sparts into the corresponding proxies. */
   for (size_t k = 0; k < *Nspart; k++) {
+
+    /* Ignore the particles we want to get rid of (inhibited, ...). */
+    if (ind_spart[k] == -1) continue;
+
+    /* Get the target node and proxy ID. */
     const int node_id = e->s->cells_top[ind_spart[k]].nodeID;
     if (node_id < 0 || node_id >= e->nr_nodes)
       error("Bad node ID %i.", node_id);
     const int pid = e->proxy_ind[node_id];
-    if (pid < 0)
+    if (pid < 0) {
       error(
           "Do not have a proxy for the requested nodeID %i for part with "
           "id=%lld, x=[%e,%e,%e].",
           node_id, s->sparts[offset_sparts + k].id,
           s->sparts[offset_sparts + k].x[0], s->sparts[offset_sparts + k].x[1],
           s->sparts[offset_sparts + k].x[2]);
+    }
 
     /* Re-link the associated gpart with the buffer offset of the spart. */
     if (s->sparts[offset_sparts + k].gpart != NULL) {
@@ -1913,23 +1928,39 @@ void engine_exchange_strays(struct engine *e, const size_t offset_parts,
           -e->proxies[pid].nr_sparts_out;
     }
 
+#ifdef SWIFT_DEBUG_CHECKS
+    if (s->sparts[offset_sparts + k].time_bin == time_bin_inhibited)
+      error("Attempting to exchange an inhibited particle");
+#endif
+
     /* Load the spart into the proxy */
     proxy_sparts_load(&e->proxies[pid], &s->sparts[offset_sparts + k], 1);
   }
 
   /* Put the gparts into the corresponding proxies. */
   for (size_t k = 0; k < *Ngpart; k++) {
+
+    /* Ignore the particles we want to get rid of (inhibited, ...). */
+    if (ind_gpart[k] == -1) continue;
+
+    /* Get the target node and proxy ID. */
     const int node_id = e->s->cells_top[ind_gpart[k]].nodeID;
     if (node_id < 0 || node_id >= e->nr_nodes)
       error("Bad node ID %i.", node_id);
     const int pid = e->proxy_ind[node_id];
-    if (pid < 0)
+    if (pid < 0) {
       error(
           "Do not have a proxy for the requested nodeID %i for part with "
           "id=%lli, x=[%e,%e,%e].",
           node_id, s->gparts[offset_gparts + k].id_or_neg_offset,
           s->gparts[offset_gparts + k].x[0], s->gparts[offset_gparts + k].x[1],
           s->gparts[offset_gparts + k].x[2]);
+    }
+
+#ifdef SWIFT_DEBUG_CHECKS
+    if (s->gparts[offset_gparts + k].time_bin == time_bin_inhibited)
+      error("Attempting to exchange an inhibited particle");
+#endif
 
     /* Load the gpart into the proxy */
     proxy_gparts_load(&e->proxies[pid], &s->gparts[offset_gparts + k], 1);
@@ -1992,6 +2023,8 @@ void engine_exchange_strays(struct engine *e, const size_t offset_parts,
     free(s->xparts);
     s->parts = parts_new;
     s->xparts = xparts_new;
+
+    /* Reset the links */
     for (size_t k = 0; k < offset_parts; k++) {
       if (s->parts[k].gpart != NULL) {
         s->parts[k].gpart->id_or_neg_offset = -k;
@@ -2008,6 +2041,8 @@ void engine_exchange_strays(struct engine *e, const size_t offset_parts,
     memcpy(sparts_new, s->sparts, sizeof(struct spart) * offset_sparts);
     free(s->sparts);
     s->sparts = sparts_new;
+
+    /* Reset the links */
     for (size_t k = 0; k < offset_sparts; k++) {
       if (s->sparts[k].gpart != NULL) {
         s->sparts[k].gpart->id_or_neg_offset = -k;
@@ -2025,6 +2060,7 @@ void engine_exchange_strays(struct engine *e, const size_t offset_parts,
     free(s->gparts);
     s->gparts = gparts_new;
 
+    /* Reset the links */
     for (size_t k = 0; k < offset_gparts; k++) {
       if (s->gparts[k].type == swift_type_gas) {
         s->parts[-s->gparts[k].id_or_neg_offset].gpart = &s->gparts[k];
diff --git a/src/space.c b/src/space.c
index 1e20835faf25f49da5f07ea8294eeefd22618fd7..7e371ea045518a8abc73ae28fd2a1b3e4b182665 100644
--- a/src/space.c
+++ b/src/space.c
@@ -606,12 +606,11 @@ void space_rebuild(struct space *s, int verbose) {
     space_sparts_get_cell_index(s, sind, cell_spart_counts,
                                 &count_inhibited_sparts, verbose);
 
-#ifdef WITH_MPI
   const int local_nodeID = s->e->nodeID;
 
-  /* Move non-local parts to the end of the list. */
-  for (size_t k = 0; k < nr_parts;) {
-    if (cells_top[ind[k]].nodeID != local_nodeID) {
+  /* Move non-local parts and inhibited parts to the end of the list. */
+  for (size_t k = 0; k < nr_parts; /* void */) {
+    if (ind[k] == -1 || cells_top[ind[k]].nodeID != local_nodeID) {
       nr_parts -= 1;
       /* Swap the particle */
       memswap(&s->parts[k], &s->parts[nr_parts], sizeof(struct part));
@@ -644,11 +643,11 @@ void space_rebuild(struct space *s, int verbose) {
       error("Failed to remove local parts from send list");
     }
   }
-#endif
+#endif /* SWIFT_DEBUG_CHECKS */
 
-  /* Move non-local sparts to the end of the list. */
-  for (size_t k = 0; k < nr_sparts;) {
-    if (cells_top[sind[k]].nodeID != local_nodeID) {
+  /* Move non-local sparts and inhibited sparts to the end of the list. */
+  for (size_t k = 0; k < nr_sparts; /* void */) {
+    if (sind[k] == -1 || cells_top[sind[k]].nodeID != local_nodeID) {
       nr_sparts -= 1;
       /* Swap the particle */
       memswap(&s->sparts[k], &s->sparts[nr_sparts], sizeof(struct spart));
@@ -679,11 +678,11 @@ void space_rebuild(struct space *s, int verbose) {
       error("Failed to remove local sparts from send list");
     }
   }
-#endif
+#endif /* SWIFT_DEBUG_CHECKS */
 
-  /* Move non-local gparts to the end of the list. */
-  for (size_t k = 0; k < nr_gparts;) {
-    if (cells_top[gind[k]].nodeID != local_nodeID) {
+  /* Move non-local gparts and inhibited parts to the end of the list. */
+  for (size_t k = 0; k < nr_gparts; /* void */) {
+    if (gind[k] == -1 || cells_top[gind[k]].nodeID != local_nodeID) {
       nr_gparts -= 1;
       /* Swap the particle */
       memswap(&s->gparts[k], &s->gparts[nr_gparts], sizeof(struct gpart));
@@ -720,7 +719,9 @@ void space_rebuild(struct space *s, int verbose) {
       error("Failed to remove local gparts from send list");
     }
   }
-#endif
+#endif /* SWIFT_DEBUG_CHECKS */
+
+#ifdef WITH_MPI
 
   /* Exchange the strays, note that this potentially re-allocates
      the parts arrays. */
@@ -796,6 +797,12 @@ void space_rebuild(struct space *s, int verbose) {
   }
   nr_sparts = s->nr_sparts;
 
+#else /* WITH_MPI */
+
+  /* Update the part and spart counters */
+  s->nr_parts = nr_parts;
+  s->nr_sparts = nr_sparts;
+
 #endif /* WITH_MPI */
 
   /* Sort the parts according to their cells. */
@@ -808,13 +815,6 @@ void space_rebuild(struct space *s, int verbose) {
   for (size_t k = 0; k < nr_parts; k++) {
     const struct part *p = &s->parts[k];
 
-    if (k >= nr_parts - count_inhibited_parts) {
-      if (p->time_bin != time_bin_inhibited)
-        error("Non-inhibited particles sorted into a cell!");
-
-      continue;
-    }
-
     if (p->time_bin == time_bin_inhibited)
       error("Inhibited particle sorted into a cell!");
 
@@ -834,7 +834,7 @@ void space_rebuild(struct space *s, int verbose) {
         p->x[2] < c->loc[2] || p->x[2] > c->loc[2] + c->width[2])
       error("part not sorted into the right top-level cell!");
   }
-#endif
+#endif /* SWIFT_DEBUG_CHECKS */
 
   /* Sort the sparts according to their cells. */
   if (nr_sparts > 0)
@@ -845,13 +845,6 @@ void space_rebuild(struct space *s, int verbose) {
   for (size_t k = 0; k < nr_sparts; k++) {
     const struct spart *sp = &s->sparts[k];
 
-    if (k >= nr_sparts - count_inhibited_sparts) {
-      if (sp->time_bin != time_bin_inhibited)
-        error("Non-inhibited particles sorted into a cell!");
-
-      continue;
-    }
-
     if (sp->time_bin == time_bin_inhibited)
       error("Inhibited particle sorted into a cell!");
 
@@ -871,24 +864,10 @@ void space_rebuild(struct space *s, int verbose) {
         sp->x[2] < c->loc[2] || sp->x[2] > c->loc[2] + c->width[2])
       error("spart not sorted into the right top-level cell!");
   }
-#endif
-
-  /* Remove the inhibited particles */
-  for (int k = nr_parts - count_inhibited_parts; k < nr_parts; ++k) {
-    bzero(&s->parts[k], sizeof(struct part));
-    s->parts[k].time_bin = time_bin_inhibited;
-  }
-  nr_parts -= count_inhibited_sparts
-
-      /* Remove the inhibited star particles */
-      for (int k = nr_sparts - count_inhibited_sparts; k < nr_sparts; ++k) {
-    bzero(&s->sparts[k], sizeof(struct spart));
-    s->sparts[k].time_bin = time_bin_inhibited;
-  }
-  nr_sparts -= count_inhibited_sparts
+#endif /* SWIFT_DEBUG_CHECKS */
 
-      /* Extract the cell counts from the sorted indices. */
-      size_t last_index = 0;
+  /* Extract the cell counts from the sorted indices. */
+  size_t last_index = 0;
   ind[nr_parts] = s->nr_cells;  // sentinel.
   for (size_t k = 0; k < nr_parts; k++) {
     if (ind[k] < ind[k + 1]) {
@@ -939,6 +918,11 @@ void space_rebuild(struct space *s, int verbose) {
   }
   nr_gparts = s->nr_gparts;
 
+#else /* WITH_MPI */
+
+  /* Update the gpart counter */
+  s->nr_gparts = nr_gparts;
+
 #endif /* WITH_MPI */
 
   /* Sort the gparts according to their cells. */
@@ -951,13 +935,6 @@ void space_rebuild(struct space *s, int verbose) {
   for (size_t k = 0; k < nr_gparts; k++) {
     const struct gpart *gp = &s->gparts[k];
 
-    if (k >= nr_gparts - count_inhibited_gparts) {
-      if (gp->time_bin != time_bin_inhibited)
-        error("Non-inhibited particles sorted into a cell!");
-
-      continue;
-    }
-
     if (gp->time_bin == time_bin_inhibited)
       error("Inhibited particle sorted into a cell!");
 
@@ -977,7 +954,7 @@ void space_rebuild(struct space *s, int verbose) {
         gp->x[2] < c->loc[2] || gp->x[2] > c->loc[2] + c->width[2])
       error("gpart not sorted into the right top-level cell!");
   }
-#endif
+#endif /* SWIFT_DEBUG_CHECKS */
 
   /* Extract the cell counts from the sorted indices. */
   size_t last_gindex = 0;
@@ -1127,7 +1104,6 @@ void space_parts_get_cell_index_mapper(void *map_data, int nr_parts,
   const double ih_x = s->iwidth[0];
   const double ih_y = s->iwidth[1];
   const double ih_z = s->iwidth[2];
-  const int num_cells = s->nr_cells;
 
   /* Init the local count buffer. */
   int *cell_counts = (int *)calloc(sizeof(int), s->nr_cells);
@@ -1171,7 +1147,7 @@ void space_parts_get_cell_index_mapper(void *map_data, int nr_parts,
 
     /* Is this particle to be removed? */
     if (p->time_bin == time_bin_inhibited) {
-      ind[k] = num_cells + 1;
+      ind[k] = -1;
       ++count_inhibited_part;
     } else {
       /* List its top-level cell index */
@@ -1228,7 +1204,6 @@ void space_gparts_get_cell_index_mapper(void *map_data, int nr_gparts,
   const double ih_x = s->iwidth[0];
   const double ih_y = s->iwidth[1];
   const double ih_z = s->iwidth[2];
-  const int num_cells = s->nr_cells;
 
   /* Init the local count buffer. */
   int *cell_counts = (int *)calloc(sizeof(int), s->nr_cells);
@@ -1271,7 +1246,7 @@ void space_gparts_get_cell_index_mapper(void *map_data, int nr_gparts,
 
     /* Is this particle to be removed? */
     if (gp->time_bin == time_bin_inhibited) {
-      ind[k] = num_cells + 1;
+      ind[k] = -1;
       ++count_inhibited_gpart;
     } else {
       /* List its top-level cell index */
@@ -1333,7 +1308,6 @@ void space_sparts_get_cell_index_mapper(void *map_data, int nr_sparts,
   const double ih_x = s->iwidth[0];
   const double ih_y = s->iwidth[1];
   const double ih_z = s->iwidth[2];
-  const int num_cells = s->nr_cells;
 
   /* Init the local count buffer. */
   int *cell_counts = (int *)calloc(sizeof(int), s->nr_cells);
@@ -1376,7 +1350,7 @@ void space_sparts_get_cell_index_mapper(void *map_data, int nr_sparts,
 
     /* Is this particle to be removed? */
     if (sp->time_bin == time_bin_inhibited) {
-      ind[k] = num_cells + 1;
+      ind[k] = -1;
       ++count_inhibited_spart;
     } else {
       /* List its top-level cell index */