diff --git a/examples/main.c b/examples/main.c
index 5ae01a9280ac84c11513137cd5b26c9e8966f7b9..049d49fa32910a6ba6b15419ba378db7bd7de80b 100644
--- a/examples/main.c
+++ b/examples/main.c
@@ -938,7 +938,7 @@ int main(int argc, char *argv[]) {
       engine_policies |= engine_policy_structure_finding;
 
     // MATTHIEU: Temporary star formation law
-    // engine_policies |= engine_policy_star_formation;
+    engine_policies |= engine_policy_star_formation;
 
     /* Initialize the engine with the space and policies. */
     if (myrank == 0) clocks_gettime(&tic);
diff --git a/src/cell.c b/src/cell.c
index 37b7be42f3aa04d79496d2913d30654af93ea45e..1c4d1f9e32a030b1f2d52ef0a5e3ff67baff2ff4 100644
--- a/src/cell.c
+++ b/src/cell.c
@@ -3633,6 +3633,8 @@ void cell_check_timesteps(struct cell *c) {
 #endif
 }
 
+void cell_add_spart(const struct engine *e, struct cell *c) {}
+
 /**
  * @brief "Remove" a gas particle from the calculation.
  *
diff --git a/src/cell.h b/src/cell.h
index 9a9f0a198769f0a1bbd9fad578a66e80d0af6e14..5d542e5f2d3bf95c5af1ceb312f69a8b31caa18d 100644
--- a/src/cell.h
+++ b/src/cell.h
@@ -460,6 +460,9 @@ struct cell {
     /*! Nr of #spart in this cell. */
     int count;
 
+    /*! Nr of #spart this cell can hold after addition of new #spart. */
+    int count_total;
+
     /*! Values of h_max before the drifts, used for sub-cell tasks. */
     float h_max_old;
 
diff --git a/src/space.c b/src/space.c
index 411d24a92631b7649298918d91725e8aca9aeb93..fd0bd9e752a3ae06e3a3e376c72a84f714eefed3 100644
--- a/src/space.c
+++ b/src/space.c
@@ -71,9 +71,15 @@ int space_subsize_self_stars = space_subsize_self_stars_default;
 int space_subdepth_grav = space_subdepth_grav_default;
 int space_maxsize = space_maxsize_default;
 
+/*! Number of extra #part we allocate memory for per top-level cell */
+int space_extra_parts = space_extra_parts_default;
+
 /*! Number of extra #spart we allocate memory for per top-level cell */
 int space_extra_sparts = space_extra_sparts_default;
 
+/*! Number of extra #gpart we allocate memory for per top-level cell */
+int space_extra_gparts = space_extra_gparts_default;
+
 /*! Expected maximal number of strays received at a rebuild */
 int space_expected_max_nr_strays = space_expected_max_nr_strays_default;
 #ifdef SWIFT_DEBUG_CHECKS
@@ -285,6 +291,8 @@ void space_regrid(struct space *s, int verbose) {
   const ticks tic = getticks();
   const integertime_t ti_current = (s->e != NULL) ? s->e->ti_current : 0;
 
+  message("REGRID!!");
+
   /* Run through the cells and get the current h_max. */
   // tic = getticks();
   float h_max = s->cell_min / kernel_gamma / space_stretch;
@@ -589,6 +597,41 @@ void space_regrid(struct space *s, int verbose) {
             clocks_getunit());
 }
 
+void space_allocate_extras(struct space *s, int verbose) {
+
+  const int local_nodeID = s->e->nodeID;
+
+  /* The current number of particles */
+  size_t nr_parts = s->nr_parts;
+  size_t nr_gparts = s->nr_gparts;
+  size_t nr_sparts = s->nr_sparts;
+
+  /* The number of particles we allocated memory for (MPI overhead) */
+  size_t size_parts = s->size_parts;
+  size_t size_gparts = s->size_gparts;
+  size_t size_sparts = s->size_sparts;
+
+  int local_cells = 0;
+  for (int i = 0; i < s->nr_cells; ++i)
+    if (s->cells_top[i].nodeID == local_nodeID) local_cells++;
+
+  const size_t num_extra_parts = local_cells * space_extra_parts;
+  const size_t num_extra_gparts = local_cells * space_extra_parts;
+  const size_t num_extra_sparts = local_cells * space_extra_parts;
+
+  if (verbose)
+    message("Requesting space for future %zd/%zd/%zd part/gpart/sparts.",
+            num_extra_parts, num_extra_gparts, num_extra_sparts);
+
+  /* Do we need to reallocate? */
+  if (nr_parts + num_extra_parts > size_parts) {
+  }
+  if (nr_gparts + num_extra_gparts > size_gparts) {
+  }
+  if (nr_sparts + num_extra_sparts > size_sparts) {
+  }
+}
+
 /**
  * @brief Re-build the cells as well as the tasks.
  *
@@ -609,8 +652,12 @@ void space_rebuild(struct space *s, int repartitioned, int verbose) {
   /* Re-grid if necessary, or just re-set the cell data. */
   space_regrid(s, verbose);
 
+  /* Allocate extra space for particles that will be created */
+  space_allocate_extras(s, verbose);
+
   struct cell *cells_top = s->cells_top;
   const integertime_t ti_current = (s->e != NULL) ? s->e->ti_current : 0;
+  const int local_nodeID = s->e->nodeID;
 
   /* The current number of particles */
   size_t nr_parts = s->nr_parts;
@@ -632,36 +679,37 @@ void space_rebuild(struct space *s, int repartitioned, int verbose) {
   const size_t g_index_size = size_gparts + space_expected_max_nr_strays;
   const size_t s_index_size = size_sparts + space_expected_max_nr_strays;
 
-  /* Run through the particles and get their cell index. Allocates
-     an index that is larger than the number of particles to avoid
-     re-allocating after shuffling. */
+  /* Allocate arrays to store the indices of the cells where particles
+     belong. We allocate extra space to allow for particles we may
+     receive from other nodes */
   int *h_index = (int *)malloc(sizeof(int) * h_index_size);
-  if (h_index == NULL) error("Failed to allocate temporary particle indices.");
-  int *cell_part_counts = (int *)calloc(sizeof(int), s->nr_cells);
-  if (cell_part_counts == NULL)
-    error("Failed to allocate cell part count buffer.");
+  int *g_index = (int *)malloc(sizeof(int) * g_index_size);
+  int *s_index = (int *)malloc(sizeof(int) * s_index_size);
+  if (h_index == NULL || g_index == NULL || s_index == NULL)
+    error("Failed to allocate temporary particle indices.");
+
+  /* Allocate counters of particles that will land in each cell */
+  int *cell_part_counts = (int *)malloc(sizeof(int) * s->nr_cells);
+  int *cell_gpart_counts = (int *)malloc(sizeof(int) * s->nr_cells);
+  int *cell_spart_counts = (int *)malloc(sizeof(int) * s->nr_cells);
+  if (cell_part_counts == NULL || cell_gpart_counts == NULL ||
+      cell_spart_counts == NULL)
+    error("Failed to allocate cell particle count buffer.");
+
+  /* Initialise the counters, including buffer space for future particles */
+  for (int i = 0; i < s->nr_cells; ++i) {
+    cell_part_counts[i] = space_extra_parts;
+    cell_gpart_counts[i] = space_extra_gparts;
+    cell_spart_counts[i] = space_extra_sparts;
+  }
+
+  /* Run through the particles and get their cell index. */
   if (size_parts > 0)
     space_parts_get_cell_index(s, h_index, cell_part_counts,
                                &count_inhibited_parts, verbose);
-
-  /* Run through the gravity particles and get their cell index. */
-  int *g_index = (int *)malloc(sizeof(int) * g_index_size);
-  if (g_index == NULL)
-    error("Failed to allocate temporary g-particle indices.");
-  int *cell_gpart_counts = (int *)calloc(sizeof(int), s->nr_cells);
-  if (cell_gpart_counts == NULL)
-    error("Failed to allocate cell gpart count buffer.");
   if (size_gparts > 0)
     space_gparts_get_cell_index(s, g_index, cell_gpart_counts,
                                 &count_inhibited_gparts, verbose);
-
-  /* Run through the star particles and get their cell index. */
-  int *s_index = (int *)malloc(sizeof(int) * s_index_size);
-  if (s_index == NULL)
-    error("Failed to allocate temporary s-particle indices.");
-  int *cell_spart_counts = (int *)calloc(sizeof(int), s->nr_cells);
-  if (cell_spart_counts == NULL)
-    error("Failed to allocate cell gpart count buffer.");
   if (size_sparts > 0)
     space_sparts_get_cell_index(s, s_index, cell_spart_counts,
                                 &count_inhibited_sparts, verbose);
@@ -675,8 +723,6 @@ void space_rebuild(struct space *s, int repartitioned, int verbose) {
     error("We just repartitioned but still found inhibited gparts.");
 #endif
 
-  const int local_nodeID = s->e->nodeID;
-
   /* Move non-local parts and inhibited parts to the end of the list. */
   if (!repartitioned && (s->e->nr_nodes > 1 || count_inhibited_parts > 0)) {
     for (size_t k = 0; k < nr_parts; /* void */) {
@@ -850,6 +896,7 @@ void space_rebuild(struct space *s, int repartitioned, int verbose) {
     s->nr_parts = nr_parts + nr_parts_exchanged;
     s->nr_gparts = nr_gparts + nr_gparts_exchanged;
     s->nr_sparts = nr_sparts + nr_sparts_exchanged;
+
   } else {
 #ifdef SWIFT_DEBUG_CHECKS
     if (s->nr_parts != nr_parts)
diff --git a/src/space.h b/src/space.h
index 93a8dc83b72566a4817d44a4222756a168d9f9b3..2444a2ed8866279281943542c0c82eee20885b72 100644
--- a/src/space.h
+++ b/src/space.h
@@ -44,7 +44,9 @@ struct cosmology;
 #define space_cellallocchunk 1000
 #define space_splitsize_default 400
 #define space_maxsize_default 8000000
-#define space_extra_sparts_default 200
+#define space_extra_parts_default 10
+#define space_extra_gparts_default 10
+#define space_extra_sparts_default 10
 #define space_expected_max_nr_strays_default 100
 #define space_subsize_pair_hydro_default 256000000
 #define space_subsize_self_hydro_default 32000