diff --git a/examples/main.c b/examples/main.c
index fd57d632b2e649730873286f049908d3abe3178f..8d4289c872ce34ba626cacffca4097c0093fe0c3 100644
--- a/examples/main.c
+++ b/examples/main.c
@@ -602,7 +602,7 @@ int main(int argc, char *argv[]) {
            clocks_getunit());
 
   /* Main simulation loop */
-  for (int j = 0; !engine_is_done(&e) && e.step != nsteps; j++) {
+  for (int j = 0; !engine_is_done(&e) && e.step - 1 != nsteps; j++) {
 
     /* Reset timers */
     timers_reset(timers_mask_all);
diff --git a/src/active.h b/src/active.h
index 38020fde8ed53a638231097643476b7ef72d6d49..02e504f762735994e6c57f7e155071fede016713 100644
--- a/src/active.h
+++ b/src/active.h
@@ -105,10 +105,12 @@ __attribute__((always_inline)) INLINE static int cell_is_all_active(
 __attribute__((always_inline)) INLINE static int part_is_active(
     const struct part *p, const struct engine *e) {
 
-  const integertime_t ti_current = e->ti_current;
-  const integertime_t ti_end = get_integer_time_end(ti_current, p->time_bin);
+  const timebin_t max_active_bin = e->max_active_bin;
+  const timebin_t part_bin = p->time_bin;
 
 #ifdef SWIFT_DEBUG_CHECKS
+  const integertime_t ti_current = e->ti_current;
+  const integertime_t ti_end = get_integer_time_end(ti_current, p->time_bin);
   if (ti_end < ti_current)
     error(
         "particle in an impossible time-zone! p->ti_end=%lld "
@@ -116,7 +118,7 @@ __attribute__((always_inline)) INLINE static int part_is_active(
         ti_end, ti_current);
 #endif
 
-  return (ti_end == ti_current);
+  return (part_bin <= max_active_bin);
 }
 
 /**
@@ -129,10 +131,13 @@ __attribute__((always_inline)) INLINE static int part_is_active(
 __attribute__((always_inline)) INLINE static int gpart_is_active(
     const struct gpart *gp, const struct engine *e) {
 
+  const timebin_t max_active_bin = e->max_active_bin;
+  const timebin_t gpart_bin = gp->time_bin;
+
+#ifdef SWIFT_DEBUG_CHECKS
   const integertime_t ti_current = e->ti_current;
   const integertime_t ti_end = get_integer_time_end(ti_current, gp->time_bin);
 
-#ifdef SWIFT_DEBUG_CHECKS
   if (ti_end < ti_current)
     error(
         "g-particle in an impossible time-zone! gp->ti_end=%lld "
@@ -140,7 +145,7 @@ __attribute__((always_inline)) INLINE static int gpart_is_active(
         ti_end, ti_current);
 #endif
 
-  return (ti_end == ti_current);
+  return (gpart_bin <= max_active_bin);
 }
 
 /**
@@ -153,10 +158,13 @@ __attribute__((always_inline)) INLINE static int gpart_is_active(
 __attribute__((always_inline)) INLINE static int spart_is_active(
     const struct spart *sp, const struct engine *e) {
 
+  const timebin_t max_active_bin = e->max_active_bin;
+  const timebin_t spart_bin = sp->time_bin;
+
+#ifdef SWIFT_DEBUG_CHECKS
   const integertime_t ti_current = e->ti_current;
   const integertime_t ti_end = get_integer_time_end(ti_current, sp->time_bin);
 
-#ifdef SWIFT_DEBUG_CHECKS
   if (ti_end < ti_current)
     error(
         "s-particle in an impossible time-zone! sp->ti_end=%lld "
@@ -164,7 +172,7 @@ __attribute__((always_inline)) INLINE static int spart_is_active(
         ti_end, ti_current);
 #endif
 
-  return (ti_end == ti_current);
+  return (spart_bin <= max_active_bin);
 }
 
 /* Are cells / particles active for kick1 tasks ? */
@@ -201,11 +209,14 @@ __attribute__((always_inline)) INLINE static int cell_is_starting(
 __attribute__((always_inline)) INLINE static int part_is_starting(
     const struct part *p, const struct engine *e) {
 
+  const timebin_t max_active_bin = e->max_active_bin;
+  const timebin_t part_bin = p->time_bin;
+
+#ifdef SWIFT_DEBUG_CHECKS
   const integertime_t ti_current = e->ti_current;
   const integertime_t ti_beg =
       get_integer_time_begin(ti_current + 1, p->time_bin);
 
-#ifdef SWIFT_DEBUG_CHECKS
   if (ti_beg > ti_current)
     error(
         "particle in an impossible time-zone! p->ti_beg=%lld "
@@ -213,7 +224,7 @@ __attribute__((always_inline)) INLINE static int part_is_starting(
         ti_beg, ti_current);
 #endif
 
-  return (ti_beg == ti_current);
+  return (part_bin <= max_active_bin);
 }
 
 /**
@@ -226,11 +237,14 @@ __attribute__((always_inline)) INLINE static int part_is_starting(
 __attribute__((always_inline)) INLINE static int gpart_is_starting(
     const struct gpart *gp, const struct engine *e) {
 
+  const timebin_t max_active_bin = e->max_active_bin;
+  const timebin_t gpart_bin = gp->time_bin;
+
+#ifdef SWIFT_DEBUG_CHECKS
   const integertime_t ti_current = e->ti_current;
   const integertime_t ti_beg =
       get_integer_time_begin(ti_current + 1, gp->time_bin);
 
-#ifdef SWIFT_DEBUG_CHECKS
   if (ti_beg > ti_current)
     error(
         "g-particle in an impossible time-zone! gp->ti_beg=%lld "
@@ -238,7 +252,7 @@ __attribute__((always_inline)) INLINE static int gpart_is_starting(
         ti_beg, ti_current);
 #endif
 
-  return (ti_beg == ti_current);
+  return (gpart_bin <= max_active_bin);
 }
 
 /**
@@ -251,11 +265,14 @@ __attribute__((always_inline)) INLINE static int gpart_is_starting(
 __attribute__((always_inline)) INLINE static int spart_is_starting(
     const struct spart *sp, const struct engine *e) {
 
+  const timebin_t max_active_bin = e->max_active_bin;
+  const timebin_t spart_bin = sp->time_bin;
+
+#ifdef SWIFT_DEBUG_CHECKS
   const integertime_t ti_current = e->ti_current;
   const integertime_t ti_beg =
       get_integer_time_begin(ti_current + 1, sp->time_bin);
 
-#ifdef SWIFT_DEBUG_CHECKS
   if (ti_beg > ti_current)
     error(
         "s-particle in an impossible time-zone! sp->ti_beg=%lld "
@@ -263,6 +280,6 @@ __attribute__((always_inline)) INLINE static int spart_is_starting(
         ti_beg, ti_current);
 #endif
 
-  return (ti_beg == ti_current);
+  return (spart_bin <= max_active_bin);
 }
 #endif /* SWIFT_ACTIVE_H */
diff --git a/src/engine.c b/src/engine.c
index facffa389e98fdeeebda222f04b2953c00b97373..2f3b3623462845c15a5285dfd75612844d35f63d 100644
--- a/src/engine.c
+++ b/src/engine.c
@@ -2804,6 +2804,18 @@ void engine_print_stats(struct engine *e) {
 
   const ticks tic = getticks();
 
+#ifdef SWIFT_DEBUG_CHECKS
+  /* Check that all cells have been drifted to the current time.
+   * That can include cells that have not
+   * previously been active on this rank. */
+  space_check_drift_point(e->s, e->ti_current);
+
+  /* Be verbose about this */
+  message("Saving statistics at t=%e.", e->time);
+#else
+  if (e->verbose) message("Saving statistics at t=%e.", e->time);
+#endif
+
   e->save_stats = 0;
 
   struct statistics stats;
@@ -3010,7 +3022,7 @@ void engine_init_particles(struct engine *e, int flag_entropy_ICs) {
 #endif
 
   /* Ready to go */
-  e->step = -1;
+  e->step = 0;
   e->forcerebuild = 1;
   e->wallclock_time = (float)clocks_diff(&time1, &time2);
 
@@ -3031,20 +3043,12 @@ void engine_step(struct engine *e) {
 
   e->tic_step = getticks();
 
-  /* Move forward in time */
-  e->ti_old = e->ti_current;
-  e->ti_current = e->ti_end_min;
-  e->step += 1;
-  e->time = e->ti_current * e->timeBase + e->timeBegin;
-  e->timeOld = e->ti_old * e->timeBase + e->timeBegin;
-  e->timeStep = (e->ti_current - e->ti_old) * e->timeBase;
-
   if (e->nodeID == 0) {
 
     /* Print some information to the screen */
-    printf("  %6d %14e %14e %10zu %10zu %10zu %21.3f\n", e->step, e->time,
-           e->timeStep, e->updates, e->g_updates, e->s_updates,
-           e->wallclock_time);
+    printf("  %6d %14e %d %14e %10zu %10zu %10zu %21.3f\n", e->step, e->time,
+           e->max_active_bin, e->timeStep, e->updates, e->g_updates,
+           e->s_updates, e->wallclock_time);
     fflush(stdout);
 
     fprintf(e->file_timesteps, "  %6d %14e %14e %10zu %10zu %10zu %21.3f\n",
@@ -3053,6 +3057,15 @@ void engine_step(struct engine *e) {
     fflush(e->file_timesteps);
   }
 
+  /* Move forward in time */
+  e->ti_old = e->ti_current;
+  e->ti_current = e->ti_end_min;
+  e->max_active_bin = get_max_active_bin(e->ti_end_min);
+  e->step += 1;
+  e->time = e->ti_current * e->timeBase + e->timeBegin;
+  e->timeOld = e->ti_old * e->timeBase + e->timeBegin;
+  e->timeStep = (e->ti_current - e->ti_old) * e->timeBase;
+
   /* Prepare the tasks to be launched, rebuild or repartition if needed. */
   engine_prepare(e);
 
@@ -3566,6 +3579,7 @@ void engine_init(struct engine *e, struct space *s,
   e->time = e->timeBegin;
   e->ti_old = 0;
   e->ti_current = 0;
+  e->max_active_bin = num_time_bins;
   e->timeStep = 0.;
   e->timeBase = 0.;
   e->timeBase_inv = 0.;
diff --git a/src/engine.h b/src/engine.h
index 35b0d4a58225e4c825eb1002ad405cb7840b8bd6..80903ee78156c7e4efb2650e59e4fa832fecbfa3 100644
--- a/src/engine.h
+++ b/src/engine.h
@@ -122,6 +122,9 @@ struct engine {
   double time;
   integertime_t ti_current;
 
+  /* The highest active bin at this time */
+  timebin_t max_active_bin;
+
   /* Time step */
   double timeStep;
 
diff --git a/src/timeline.h b/src/timeline.h
index 25ab231e24b85f2a4b6b3d44f024588420e432ea..0f38ff3e9421c122b61caf74290c170b62b2dd92 100644
--- a/src/timeline.h
+++ b/src/timeline.h
@@ -37,7 +37,8 @@ typedef char timebin_t;
 /*! The maximal number of timesteps in a simulation */
 #define max_nr_timesteps (1LL << (num_time_bins + 1))
 
-#define time_bin_inactive (num_time_bins + 2)
+/*! Fictious time-bin to hold inhibited particles */
+#define time_bin_inhibited (num_time_bins + 2)
 
 /**
  * @brief Returns the integer time interval corresponding to a time bin